<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><div id="myscoll"></div><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>ECMAScript基础 | 晚夜微雨问海棠のBlog</title><meta name="keywords" content="ECMAScript基础"><meta name="author" content="晚夜微雨问海棠"><meta name="copyright" content="晚夜微雨问海棠"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="ECMAScript （ES6）ECMAScript 简介 阮一峰的博客地址：http:&#x2F;&#x2F;jsrun.net&#x2F;t&#x2F;dZKKp ECMAScript 6.0（以下简称 ES6）是 JavaScript 语言的下一代标准，已经在2015年6月正式发布了。它的目标，是使得 JavaScript 语言可以用来编写复杂的大型应用程序，成为企业级开发语言。 ECMAScript 和 JavaScript 的">
<meta property="og:type" content="article">
<meta property="og:title" content="ECMAScript基础">
<meta property="og:url" content="http://example.com/posts/50839dad.html">
<meta property="og:site_name" content="晚夜微雨问海棠のBlog">
<meta property="og:description" content="ECMAScript （ES6）ECMAScript 简介 阮一峰的博客地址：http:&#x2F;&#x2F;jsrun.net&#x2F;t&#x2F;dZKKp ECMAScript 6.0（以下简称 ES6）是 JavaScript 语言的下一代标准，已经在2015年6月正式发布了。它的目标，是使得 JavaScript 语言可以用来编写复杂的大型应用程序，成为企业级开发语言。 ECMAScript 和 JavaScript 的">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://s1.ax1x.com/2022/11/09/zS8LRA.jpg">
<meta property="article:published_time" content="2022-11-09T08:37:01.000Z">
<meta property="article:modified_time" content="2023-01-10T08:38:46.214Z">
<meta property="article:author" content="晚夜微雨问海棠">
<meta property="article:tag" content="前端体系">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://s1.ax1x.com/2022/11/09/zS8LRA.jpg"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="http://example.com/posts/50839dad"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//fonts.googleapis.com" crossorigin=""/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="manifest" href="/manifest.json"/><meta name="msapplication-TileColor" content="#49b1f5"/><link rel="apple-touch-icon" sizes="180x180" href="/img/siteicon/128.png"/><link rel="icon" type="image/png" sizes="32x32" href="/img/siteicon/32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/img/siteicon/16.png"/><link rel="mask-icon" href="/img/siteicon/128.png" color="#5bbad5"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;display=swap" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":false,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"简"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":150},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: true
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":650,"languages":{"author":"作者: 晚夜微雨问海棠","link":"链接: ","source":"来源: 晚夜微雨问海棠のBlog","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#1f1f1f","position":"top-right"},
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isAnchor: true
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'ECMAScript基础',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2023-01-10 16:38:46'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'"> <link rel="stylesheet" href="/swiper/swiper.min.css"> <link rel="stylesheet" href="/swiper/swiperstyle.css"> <link rel="stylesheet" href="/css/rightMenu.css"> <link rel="stylesheet" href="/css/constrain.css"><!-- hexo injector head_end start --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-card-history/baiduhistory/css/main.css"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-categories-card@1.0.0/lib/categorybar.css"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu/lib/clock.min.css" /><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-double-row-display@1.00/cardlistpost.min.css"/>
<style>#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap > .tags:before {content:"\A";
  white-space: pre;}#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap > .tags > .article-meta__separator{display:none}</style>
<link rel="stylesheet" href="https://cdn.cbd.int/anzhiyu-blog@2.0.3/css/runtime/runtime.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiper.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiperstyle.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-wowjs/lib/animate.min.css" media="print" onload="this.media='screen'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/assets/font-awesome-animation.min.css" media="defer" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/tag_plugins.css" media="defer" onload="this.media='all'"><script src="https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/assets/carousel-touch.js"></script><!-- hexo injector head_end end --><meta name="generator" content="Hexo 6.2.0"><link rel="alternate" href="/atom.xml" title="晚夜微雨问海棠のBlog" type="application/atom+xml">
</head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><div id="web_bg" style="background:url(https://s1.ax1x.com/2022/11/09/zS8LRA.jpg);background-attachment: local;background-position: center;background-size: cover;background-repeat: no-repeat;"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://img2.woyaogexing.com/2022/06/28/de1ce3dc65468fd4!400x400.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">97</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">31</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">17</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/bangumis/index.html"><i class="fa-fw fas fa-home"></i><span> 追番</span></a></div><div class="menus_item"><a class="site-page" href="/comments/"><i class="fa-fw fas fa-envelope"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 生活馆</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" target="_blank" rel="noopener" href="http://81.69.189.243:8082/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友情链接</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://s1.ax1x.com/2022/11/09/zS8LRA.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">晚夜微雨问海棠のBlog</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/bangumis/index.html"><i class="fa-fw fas fa-home"></i><span> 追番</span></a></div><div class="menus_item"><a class="site-page" href="/comments/"><i class="fa-fw fas fa-envelope"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 生活馆</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" target="_blank" rel="noopener" href="http://81.69.189.243:8082/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友情链接</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">ECMAScript基础</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-11-09T08:37:01.000Z" title="发表于 2022-11-09 16:37:01">2022-11-09</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2023-01-10T08:38:46.214Z" title="更新于 2023-01-10 16:38:46">2023-01-10</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">23.7k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>95分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="ECMAScript基础"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="ECMAScript-（ES6）"><a href="#ECMAScript-（ES6）" class="headerlink" title="ECMAScript （ES6）"></a>ECMAScript （ES6）</h1><h2 id="ECMAScript-简介"><a href="#ECMAScript-简介" class="headerlink" title="ECMAScript 简介"></a>ECMAScript 简介</h2><ol>
<li>阮一峰的博客地址：<a target="_blank" rel="noopener" href="http://jsrun.net/t/dZKKp">http://jsrun.net/t/dZKKp</a></li>
<li>ECMAScript 6.0（以下简称 ES6）是 JavaScript 语言的下一代标准，已经在2015年6月正式发布了。它的目标，是使得 JavaScript 语言可以用来编写复杂的大型应用程序，成为企业级开发语言。</li>
<li>ECMAScript 和 JavaScript 的关系是，前者是后者的规格，后者是前者的一种实现（另外的 ECMAScript 方言还有 Jscript 和 ActionScript）。日常场合，这两个词是可以互换的</li>
<li>ES6 既是一个历史名词，也是一个泛指，含义是5.1版以后的 JavaScript 的下一代标准，涵盖了ES2015、ES2016、ES2017等等，而ES2015 则是正式名称，特指该年发布的正式版本的语言标准。ES6一般是指 ES2015 标准，但有时也是泛指“下一代 JavaScript 语言”。</li>
<li>网上有两种界定，一种是ES6新版本的统称，无论ES2015、ES2016、ES2017等等，都叫做ES6；还有一种就是每年一个版本比如ES6对应的是ES2015、ES7对应的是ES2016、ES8对应的是ES2017等等，它们统称为ESN（ECMAScript New Version）。这两种表达的都是一个意思，以后去面试也好，看博客学习也好要知道表达的是什么就可以了</li>
</ol>
<h2 id="let-和-const命令"><a href="#let-和-const命令" class="headerlink" title="let 和 const命令"></a>let 和 const命令</h2><ol>
<li>在学习JavaScript的时候使用 var去声明变量，我们今天拓展两个，let 和 const</li>
<li>let 常用于变量的声明</li>
<li>const 常用于常量的声明</li>
</ol>
<h3 id="le-和-const都有块级作用域"><a href="#le-和-const都有块级作用域" class="headerlink" title="le 和 const都有块级作用域"></a>le 和 const都有块级作用域</h3><ol>
<li>什么是块级作用域，简单理解就是一个大括号就是一个块</li>
<li>我们先看一个 var定义的变量</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(<span class="literal">false</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> a = <span class="number">100</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a) <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure>
<ol>
<li>注意：undefined 不是错误，而是一种特殊的数据类型，是合法的，允许存在的，所以就说明一个问题，if语句的括号没有限制住a的作用域，所以我们可以这么认为 <code>var定义的变量是没有块级作用域的</code></li>
<li>我们再来看一下 let 和 const 的定义的变量</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//let定义的变量</span></span><br><span class="line"><span class="keyword">if</span>(<span class="literal">true</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> b = <span class="number">200</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b) <span class="comment">//报错</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// const定义的变量</span></span><br><span class="line"><span class="keyword">if</span>(<span class="literal">false</span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> c = <span class="number">300</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(c) <span class="comment">//报错</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<ol>
<li>你会发现 let 和 const 定义的变量，无论 if条件中为 true 或者 false，内部的括号都会封闭自己的作用域总结</li>
<li>let 和 const 定义的变量有一个特点，就是在哪一级定义的，就在哪一级使用，因为有自己的块限制</li>
<li>如果有错误，需要解决错误才能往下执行</li>
<li>不仅 if条件语句可以作为块级作用域，循环语句也可以</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = [];</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">  a[i] = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line">a[<span class="number">6</span>](); <span class="comment">// 10</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">如果使用<span class="keyword">let</span></span><br><span class="line"><span class="keyword">var</span> a = [];</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">  a[i] = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line">a[<span class="number">6</span>](); <span class="comment">// 6</span></span><br></pre></td></tr></table></figure>
<h3 id="let和const声明的变量都没有声明提升"><a href="#let和const声明的变量都没有声明提升" class="headerlink" title="let和const声明的变量都没有声明提升"></a>let和const声明的变量都没有声明提升</h3><ol>
<li>什么是变量声明的提升? 还是从 var定义的变量开始</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a) <span class="comment">// undefined</span></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">100</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>你会发现 a会返回 undefined，并不会报错，那是因为 a此时已经定义了，并且提升到了当前作用域（全局作用域或者函数的作用域）的最顶部</li>
<li>所以上面的代码和下面的代码是等价的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a) <span class="comment">// undefined</span></span><br><span class="line">a = <span class="number">100</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>此时你就会发现 var是有变量声明提升的。</li>
<li>我们再看 let 和 const</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// let 声明</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b) <span class="comment">// 报错</span></span><br><span class="line"><span class="keyword">let</span> b = <span class="number">200</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// const 声明</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(c) <span class="comment">// 报错</span></span><br><span class="line"><span class="keyword">const</span> c = <span class="number">300</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>上面错误信息的大致意思就是 c不能再初始化之前使用，所以 let 和 const 不能进行变量声明提升，必须在变量的声明后进行使用</li>
</ol>
<h3 id="let-和-const-是会出现暂时性死区"><a href="#let-和-const-是会出现暂时性死区" class="headerlink" title="let 和 const 是会出现暂时性死区"></a>let 和 const 是会出现暂时性死区</h3><ol>
<li>什么是暂时性死区？</li>
<li>暂时性死区：只要块级作用域内存在 let 或 const，它所声明的变量就“绑定”(binding)这个区域，不再受外部影响</li>
<li>let 和 var 声明的同一个变量之间，这中间的部分就叫暂时性死区，代表不能在中间任何地方使用</li>
<li>先看 var定义的变量</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//var定义</span></span><br><span class="line"><span class="keyword">var</span> tmp = <span class="number">123</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">  tmp = <span class="string">&#x27;abc&#x27;</span>;</span><br><span class="line">  <span class="keyword">var</span> tmp;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>我们再看 let 和 const 定义的变量</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// var 声明</span></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">100</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a) <span class="comment">// 输出200</span></span><br><span class="line"><span class="keyword">let</span> a = <span class="number">300</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// let 声明</span></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">100</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a) <span class="comment">// 直接报错，从 var定义的a,到let 定义的a 之间的部分叫：暂时性死区</span></span><br><span class="line"><span class="keyword">let</span> a = <span class="number">300</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// ========================================================================</span></span><br><span class="line"><span class="comment">// let 定义</span></span><br><span class="line"><span class="keyword">var</span> tmp = <span class="number">123</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">  tmp = <span class="string">&#x27;abc&#x27;</span>; <span class="comment">// 报错</span></span><br><span class="line">  <span class="keyword">let</span> tmp;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// const 定义</span></span><br><span class="line"><span class="keyword">var</span> tmp = <span class="number">123</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">  tmp = <span class="string">&#x27;abc&#x27;</span>; <span class="comment">// 报错</span></span><br><span class="line">  <span class="keyword">const</span> tmp;</span><br><span class="line">&#125;</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">var</span> a = <span class="number">100</span>;</span><br><span class="line">  <span class="keyword">let</span> a = <span class="number">200</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>我们会发现重复定义变量也会报错</li>
<li>暂时性死区和重复定义有着一定关联关系，我们所说的暂时性死区和重复定义变量都是需要避免的，会报错影响我们的主流程的，所以一定要理解含义，而不是去模仿暂时性死区或者重复定义变量的问题</li>
</ol>
<h3 id="let定义的是变量，const定义的是常量"><a href="#let定义的是变量，const定义的是常量" class="headerlink" title="let定义的是变量，const定义的是常量"></a>let定义的是变量，const定义的是常量</h3><ol>
<li>我们之前学习的var定义的就是变量，let和之有类似</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="number">100</span>;</span><br><span class="line">a = <span class="number">200</span>; <span class="comment">// 正常修改</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> b = <span class="number">100</span>;</span><br><span class="line">b = <span class="number">200</span>; <span class="comment">// 报错</span></span><br></pre></td></tr></table></figure>
<ol>
<li>所以你会发现 const 定义的是常量，常量是不允许修改的，什么时候会用到常量，比如我们定义一个基数（PI）const PI = 3.1415926…这个PI常量就一定不能修改</li>
</ol>
<h3 id="let-和-const定义的全局变量不是-window的属性"><a href="#let-和-const定义的全局变量不是-window的属性" class="headerlink" title="let 和 const定义的全局变量不是 window的属性"></a>let 和 const定义的全局变量不是 window的属性</h3><ol>
<li>var定义的全局变量是 window的属性</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">12345</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">window</span>.<span class="property">a</span>) <span class="comment">// 12345</span></span><br></pre></td></tr></table></figure>
<ol>
<li>let 和 const定义的全局变量不会成为window的属性</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="number">12345</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">window</span>.<span class="property">a</span>) <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure>
<h2 id="变量的解构和赋值"><a href="#变量的解构和赋值" class="headerlink" title="变量的解构和赋值"></a>变量的解构和赋值</h2><h3 id="自动解构"><a href="#自动解构" class="headerlink" title="自动解构"></a>自动解构</h3><ol>
<li>只有数组和对象能够自动解构</li>
<li>ES6中允许从数组中提取，安装对应的位置，对变量进行赋值，对象也是相同的道理</li>
<li>我们先看一下基本的解构和赋值</li>
<li>数组的解构</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a,b,c] = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a); <span class="comment">// 1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b); <span class="comment">// 2</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(c); <span class="comment">// 3</span></span><br></pre></td></tr></table></figure>
<ol>
<li>对象的解构</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> &#123;a,b,c&#125; = &#123;<span class="string">&quot;a&quot;</span>:<span class="number">2</span>, <span class="string">&quot;b&quot;</span>: <span class="number">3</span>, <span class="string">&quot;c&quot;</span>:<span class="number">4</span>&#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a); <span class="comment">// 2</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b); <span class="comment">// 3</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(c); <span class="comment">// 4</span></span><br></pre></td></tr></table></figure>
<ol>
<li>简单看一下应用场景，比如对象的解构</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 函数的形参就是对象的解构</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">People</span>(<span class="params">&#123;name,age,sex,height&#125;</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(name,age,sex,height)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 赋值</span></span><br><span class="line"><span class="keyword">var</span> xiaoming = <span class="keyword">new</span> <span class="title class_">People</span>(&#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&quot;小明&quot;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">18</span>,</span><br><span class="line">  <span class="attr">sex</span>: <span class="string">&quot;男&quot;</span>,</span><br><span class="line">  <span class="attr">height</span>: <span class="number">183</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>数组的解构和赋值的应用场景，实现一个换值的场景</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">100</span>;</span><br><span class="line"><span class="keyword">var</span> b = <span class="number">200</span>;</span><br><span class="line"><span class="keyword">var</span> c = a;</span><br><span class="line">a = b;</span><br><span class="line">b = c;</span><br></pre></td></tr></table></figure>
<ol>
<li>数组解构</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a,b] = [<span class="number">100</span>,<span class="number">200</span>];</span><br><span class="line">[b,a] = [a,b];</span><br></pre></td></tr></table></figure>
<h3 id="解构是一一对应的，无论内部结构多复杂"><a href="#解构是一一对应的，无论内部结构多复杂" class="headerlink" title="解构是一一对应的，无论内部结构多复杂"></a>解构是一一对应的，无论内部结构多复杂</h3><ol>
<li>需要注意的是解构的过程是一个一一对应的过程，这个过程很复杂也很抽象，我们需要注意的一点是数组对数组，对象对对象，</li>
<li>下面的写法是错误的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> &#123;a,b,c&#125; = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a,b,c)</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的结果是undefined，因为不能解构出内容</li>
<li>情况一</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> [foo, [[bar], baz]] = [<span class="number">1</span>, [[<span class="number">2</span>], <span class="number">3</span>]];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(foo,bar,baz)</span><br></pre></td></tr></table></figure>
<ol>
<li>情况二</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> [ , , third] = [<span class="string">&quot;foo&quot;</span>, <span class="string">&quot;bar&quot;</span>, <span class="string">&quot;baz&quot;</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(third)</span><br></pre></td></tr></table></figure>
<h3 id="剩余参数"><a href="#剩余参数" class="headerlink" title="剩余参数"></a>剩余参数</h3><ol>
<li>我们可能会遇到变量定义的内容少，复制的内容多</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a,b,c] = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(c)</span><br></pre></td></tr></table></figure>
<ol>
<li>此时如果我们想输出剩余所有的内容，此时需要用到…预算符</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a,b,...c] = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(c)</span><br></pre></td></tr></table></figure>
<ol>
<li>需要注意的是…只能使用在最后一个参数上</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a,…b,c] = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>]</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的代码是错误的</li>
</ol>
<h3 id="强制结构"><a href="#强制结构" class="headerlink" title="强制结构"></a>强制结构</h3><ol>
<li>我们也会遇到强制结构，所有的内容解构普通的数据（非数组和非对象）</li>
<li>比如下面的代码</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(...arr)</span><br></pre></td></tr></table></figure>
<ol>
<li>对象也可以实现强制解构，但是不能单独解构，必须要依赖一个解构器</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">a</span>: <span class="number">1</span>,</span><br><span class="line">  <span class="attr">b</span>: <span class="number">2</span>,</span><br><span class="line">  <span class="attr">c</span>: <span class="number">3</span>,</span><br><span class="line">  <span class="attr">d</span>: <span class="number">4</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj2 = &#123;</span><br><span class="line">  ...obj,</span><br><span class="line">  <span class="attr">e</span>: <span class="number">5</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj2)</span><br></pre></td></tr></table></figure>
<ol>
<li>对象解构常用于修改某一个值</li>
<li>比如下面的代码</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">a</span>: <span class="number">1</span>,</span><br><span class="line">  <span class="attr">b</span>: <span class="number">2</span>,</span><br><span class="line">  <span class="attr">c</span>: <span class="number">3</span>,</span><br><span class="line">  <span class="attr">d</span>: <span class="number">4</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">obj = &#123;</span><br><span class="line">  ...obj,</span><br><span class="line">  <span class="attr">a</span>: <span class="number">100</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj)</span><br></pre></td></tr></table></figure>
<ol>
<li>函数也可以实现强制解构，下面的方法是最快的将函数中 arguments类数组对象转换为普通数组的方法</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fun = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> arr = [...<span class="variable language_">arguments</span>]</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(arr)</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">fun</span>(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>)</span><br></pre></td></tr></table></figure>
<h3 id="字符串的解构和赋值"><a href="#字符串的解构和赋值" class="headerlink" title="字符串的解构和赋值"></a>字符串的解构和赋值</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> [a, b, c, d, e] = <span class="string">&#x27;hello&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a,b,c,d,e)</span><br></pre></td></tr></table></figure>
<h2 id="字符串的扩展"><a href="#字符串的扩展" class="headerlink" title="字符串的扩展"></a>字符串的扩展</h2><h3 id="字符串的遍历"><a href="#字符串的遍历" class="headerlink" title="字符串的遍历"></a>字符串的遍历</h3><ol>
<li>字符串也可以实现遍历</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> codePoint <span class="keyword">of</span> <span class="string">&#x27;mashibing&#x27;</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(codePoint)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="includes、startsWidth、endsWith方法"><a href="#includes、startsWidth、endsWith方法" class="headerlink" title="includes、startsWidth、endsWith方法"></a>includes、startsWidth、endsWith方法</h3><ol>
<li>includes方法可以进行对字符串的精确查询</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;mashibing&quot;</span>.<span class="title function_">includes</span>(<span class="string">&quot;i&quot;</span>))</span><br></pre></td></tr></table></figure>
<ol>
<li>includes()内部的参数i表示匹配的字符串，mashibing表示的是数据源，意思就是从数据源中匹配是否有对应的字符串，返回的是布尔值</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// startsWidth查询</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;mashibing&quot;</span>.<span class="title function_">startsWith</span>(<span class="string">&quot;ma&quot;</span>)) <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// endsWidth查询</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;mashibing&quot;</span>.<span class="title function_">endsWith</span>(<span class="string">&quot;ng&quot;</span>)) <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<ol>
<li>注意，上面的三个方法都是精确匹配，不是乱序匹配，比如includes下面的结果返回的是false</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;mashibing&quot;</span>.<span class="title function_">includes</span>(<span class="string">&quot;im&quot;</span>))</span><br></pre></td></tr></table></figure>
<ol>
<li>结果是false，因为i和m虽然都在mashibing字符串中存在，但是并不是安装字符串顺序查询的，所以返回false</li>
</ol>
<h3 id="repeat字符串循环"><a href="#repeat字符串循环" class="headerlink" title="repeat字符串循环"></a>repeat字符串循环</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;ha&quot;</span>.<span class="title function_">repeat</span>(<span class="number">4</span>)) <span class="comment">// hahahahaha</span></span><br></pre></td></tr></table></figure>
<h3 id="padStart和padEnd补全方法"><a href="#padStart和padEnd补全方法" class="headerlink" title="padStart和padEnd补全方法"></a>padStart和padEnd补全方法</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;shujuyuan&quot;</span>.<span class="title function_">padStart</span>(<span class="number">16</span>,<span class="string">&quot;ac&quot;</span>))</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;shujuyuan&quot;</span>.<span class="title function_">padEnd</span>(<span class="number">16</span>,<span class="string">&quot;ab&quot;</span>))</span><br></pre></td></tr></table></figure>
<h3 id="模板字符串★"><a href="#模板字符串★" class="headerlink" title="模板字符串★"></a>模板字符串★</h3><ol>
<li>模板字符串是以后我们工作中常用的写法</li>
<li>我们接触模板字符串之前的字符串拼接</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> num = <span class="number">10</span>;</span><br><span class="line"><span class="keyword">var</span> str = <span class="string">&quot;今天妈妈给了我&quot;</span>+num+<span class="string">&quot;元零花钱&quot;</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>使用模板字符串</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> num = <span class="number">10</span>;</span><br><span class="line"><span class="keyword">var</span> str2 = <span class="string">`今天爸爸给了我<span class="subst">$&#123;num&#125;</span>元`</span></span><br></pre></td></tr></table></figure>
<ol>
<li>使用反引号``表示字符串，使用${}来表示要拼接或者计算、执行或者转换的参数</li>
<li>${}内部可以是变量、也可以是函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">fun</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="number">2000</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> str3 = <span class="string">`今天爸爸给了我<span class="subst">$&#123;fun()&#125;</span>元`</span></span><br></pre></td></tr></table></figure>
<ol>
<li>${}内部可以进行计算</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> str3 = <span class="string">`今天爸爸给了我<span class="subst">$&#123;<span class="number">5</span>+<span class="number">8</span>&#125;</span>元`</span></span><br></pre></td></tr></table></figure>
<h2 id="数组的扩展★"><a href="#数组的扩展★" class="headerlink" title="数组的扩展★"></a>数组的扩展★</h2><ol>
<li>注意，数组的拓展方法返回的都是一个新函数</li>
</ol>
<h3 id="forEach方法"><a href="#forEach方法" class="headerlink" title="forEach方法"></a>forEach方法</h3><ol>
<li>我们之前学习的遍历都是for(var i = 0; i &lt; 100; i++)样式的，ES6提供了forEach数组遍历</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="string">&quot;南风&quot;</span>,<span class="string">&quot;西风&quot;</span>,<span class="string">&quot;幺鸡&quot;</span>,<span class="string">&quot;白板&quot;</span>];</span><br><span class="line">arr.<span class="title function_">forEach</span>(<span class="keyword">function</span>(<span class="params">item,index</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`<span class="subst">$&#123;item&#125;</span>的下标为<span class="subst">$&#123;index&#125;</span>`</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>参数一共有两个，第一个item表示的是对应的数组的每一项值，index表示对应值的下标</li>
</ol>
<h3 id="map方法"><a href="#map方法" class="headerlink" title="map方法"></a>map方法</h3><ol>
<li>map方法表示的是映射，返回的是一个全新的数组，新数组的每一项都是原数组的映射</li>
<li>比如我们要让下面的数组每一项值都乘以2</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]</span><br><span class="line"><span class="keyword">var</span> arr2 = arr.<span class="title function_">map</span>(<span class="keyword">function</span>(<span class="params">item,index</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> item *<span class="number">2</span>;</span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr2)</span><br></pre></td></tr></table></figure>
<h3 id="filter方法"><a href="#filter方法" class="headerlink" title="filter方法"></a>filter方法</h3><ol>
<li>filter方法，过滤旧的数组，返回新的数组集合</li>
<li>比如我们想让下面的数组过滤掉奇数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>]</span><br><span class="line"><span class="keyword">var</span> arr2 = arr.<span class="title function_">filter</span>(<span class="keyword">function</span>(<span class="params">item</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> item % <span class="number">2</span> == <span class="number">0</span>;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>filter中的参数是函数，这个return为true的值会返回的到新的数组中</li>
<li>再比如我们顾虑JSON内容，返回分数大于等于30的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [</span><br><span class="line">  &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;小明&quot;</span>, <span class="string">&quot;score&quot;</span>: <span class="number">10</span>&#125;,</span><br><span class="line">  &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;小红&quot;</span>, <span class="string">&quot;score&quot;</span>: <span class="number">20</span>&#125;,</span><br><span class="line">  &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;小工&quot;</span>, <span class="string">&quot;score&quot;</span>: <span class="number">30</span>&#125;,</span><br><span class="line">  &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;小发&quot;</span>, <span class="string">&quot;score&quot;</span>: <span class="number">40</span>&#125;,</span><br><span class="line">  &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;小吕&quot;</span>, <span class="string">&quot;score&quot;</span>: <span class="number">50</span>&#125;</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr2 = arr.<span class="title function_">filter</span>(<span class="keyword">function</span>(<span class="params">item</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> item.<span class="property">score</span> &gt;= <span class="number">30</span>;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h3 id="reduce方法"><a href="#reduce方法" class="headerlink" title="reduce方法"></a>reduce方法</h3><ol>
<li>reduce方法表示迭代遍历，每一项遍历都可以使用上一项遍历时候的结果</li>
<li>reduce函数里面有两个参数，我们用a,b去表示</li>
<li>看一下a,b分别是什么意思</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="string">&quot;白板&quot;</span>,<span class="string">&quot;幺鸡&quot;</span>,<span class="string">&quot;南风&quot;</span>,<span class="string">&quot;红中&quot;</span>,<span class="string">&quot;发财&quot;</span>];</span><br><span class="line"></span><br><span class="line">arr.<span class="title function_">reduce</span>(<span class="keyword">function</span>(<span class="params">a,b</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(a,b)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>a除了第一项之外都是 undefined，是因为a取决于上一次的计算结果，所以除了初始化的第一次知道自己是谁，剩下的都需要计算返回结果</li>
<li>b就是依次从第二项开始遍历的结果</li>
<li>此时我们可以看一下a的返回</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">arr.<span class="title function_">reduce</span>(<span class="keyword">function</span>(<span class="params">a,b</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br><span class="line">  <span class="keyword">return</span> a + b</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>我们知道字符串的相加就是拼接，所以我们看a的最后返回</li>
</ol>
<h4 id="reduce的机理"><a href="#reduce的机理" class="headerlink" title="reduce的机理"></a>reduce的机理</h4><ol>
<li>a表示遍历前一项的时候return 的值，b表示当前这一项的值。</li>
<li>系统会自动从下标为1的开始遍历，遍历下标为1项的时候，a的值是第0项</li>
<li>最后一项的return，就是最后结果的返回</li>
<li>例子1：求数组的总和</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>];</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> result = arr.<span class="title function_">reduce</span>(<span class="keyword">function</span>(<span class="params">a,b</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> a + b;</span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result)</span><br></pre></td></tr></table></figure>
<ol>
<li>例子2：求 数组的最大值</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">23</span>,<span class="number">123</span>,<span class="number">23</span>,<span class="number">423</span>,<span class="number">4</span>,<span class="number">234</span>,<span class="number">23</span>,<span class="number">4</span>,<span class="number">2131231</span>,<span class="number">423</span>,<span class="number">42</span>,<span class="number">34</span>,<span class="number">234</span>,<span class="number">354</span>,<span class="number">53</span>,<span class="number">46</span>];</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> result = arr.<span class="title function_">reduce</span>(<span class="keyword">function</span>(<span class="params">a,b</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> a &gt;= b ? a : b;</span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result)</span><br></pre></td></tr></table></figure>
<h3 id="综合应用"><a href="#综合应用" class="headerlink" title="综合应用"></a>综合应用</h3><ol>
<li>第一题，在不更改xiaoming的情况下，返回一个新对象，这个对象和xiaoming相同，仅仅让xiaoming的年龄变为19</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaoming = &#123;</span><br><span class="line">      <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小明&quot;</span>,</span><br><span class="line">      <span class="string">&quot;age&quot;</span>: <span class="number">16</span>,</span><br><span class="line">      <span class="string">&quot;sex&quot;</span>: <span class="string">&quot;男&quot;</span>,</span><br><span class="line">      <span class="string">&quot;family&quot;</span>: [</span><br><span class="line">        &#123;</span><br><span class="line">          <span class="string">&quot;relation&quot;</span>: <span class="string">&quot;父亲&quot;</span>,</span><br><span class="line">          <span class="string">&quot;age&quot;</span>: <span class="number">46</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">          <span class="string">&quot;relation&quot;</span>: <span class="string">&quot;父亲&quot;</span>,</span><br><span class="line">          <span class="string">&quot;age&quot;</span>: <span class="number">44</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">          <span class="string">&quot;relation&quot;</span>: <span class="string">&quot;姐姐&quot;</span>,</span><br><span class="line">          <span class="string">&quot;age&quot;</span>: <span class="number">20</span></span><br><span class="line">        &#125;</span><br><span class="line">      ]</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>答案</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaoming2 = &#123;</span><br><span class="line">  ...xiaoming,</span><br><span class="line">  <span class="string">&quot;age&quot;</span>: <span class="number">19</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>题目2，还是上面的关系，在不更改xiaoming的情况下，让父亲的年龄变为48</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaoming3 = &#123;</span><br><span class="line">  ...xiaoming,</span><br><span class="line">  <span class="string">&quot;family&quot;</span>: xiaoming.<span class="property">family</span>.<span class="title function_">map</span>(<span class="keyword">function</span>(<span class="params">item</span>)&#123;</span><br><span class="line">    <span class="comment">// 如果这一项的name是父亲，此时将父亲的年龄变为48</span></span><br><span class="line">    <span class="keyword">if</span>(item.<span class="property">relation</span> == <span class="string">&quot;父亲&quot;</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> &#123;</span><br><span class="line">        ...item,</span><br><span class="line">        <span class="string">&quot;age&quot;</span>: <span class="number">48</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 剩下的不变</span></span><br><span class="line">    <span class="keyword">return</span> item;</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>题目3，在不更改xiaohong的情况下，让小红只有大于15岁的朋友</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaohong = &#123;</span><br><span class="line">  <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小红&quot;</span>,</span><br><span class="line">  <span class="string">&quot;age&quot;</span>: <span class="number">14</span>,</span><br><span class="line">  <span class="string">&quot;sex&quot;</span>: <span class="string">&quot;女&quot;</span>,</span><br><span class="line">  <span class="string">&quot;friends&quot;</span>: [</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小明&quot;</span>,</span><br><span class="line">      <span class="string">&quot;age&quot;</span>: <span class="number">10</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小刚&quot;</span>,</span><br><span class="line">      <span class="string">&quot;age&quot;</span>: <span class="number">14</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小兰&quot;</span>,</span><br><span class="line">      <span class="string">&quot;age&quot;</span>: <span class="number">16</span></span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小马&quot;</span>,</span><br><span class="line">      <span class="string">&quot;age&quot;</span>: <span class="number">17</span></span><br><span class="line">    &#125;,</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>答案：</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaohong2 = &#123;</span><br><span class="line">  ...xiaohong,</span><br><span class="line">  <span class="string">&quot;friends&quot;</span>: xiaohong.<span class="property">friends</span>.<span class="title function_">filter</span>(<span class="keyword">function</span>(<span class="params">item</span>)&#123;</span><br><span class="line">    <span class="keyword">return</span> item.<span class="property">age</span> &gt; <span class="number">15</span></span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>题目4，在不更改xiaohong的情况下，让小红增加一个朋友小王</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaohong3 = &#123;</span><br><span class="line">  ...xiaohong,</span><br><span class="line">  <span class="string">&quot;friends&quot;</span>: [</span><br><span class="line">    ...xiaohong.<span class="property">friends</span>,&#123;</span><br><span class="line">      <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小王&quot;</span>,</span><br><span class="line">      <span class="string">&quot;age&quot;</span>: <span class="number">15</span></span><br><span class="line">    &#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>题目5，在不更改小红的情况下，增加一个朋友小花，年龄是所有朋友年龄最大的朋友的两倍；</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaohong4 = &#123;</span><br><span class="line">  ...xiaohong,</span><br><span class="line">  <span class="string">&quot;friends&quot;</span>: [</span><br><span class="line">    ...xiaohong.<span class="property">friends</span>,</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="string">&quot;name&quot;</span>:<span class="string">&quot;小花&quot;</span>,</span><br><span class="line">      <span class="string">&quot;age&quot;</span>: xiaohong.<span class="property">friends</span>.<span class="title function_">reduce</span>(<span class="keyword">function</span>(<span class="params">a,b</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> a.<span class="property">age</span> &gt; b.<span class="property">age</span> ? a : b</span><br><span class="line">      &#125;).<span class="property">age</span> * <span class="number">2</span></span><br><span class="line">    &#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="includes方法"><a href="#includes方法" class="headerlink" title="includes方法"></a>includes方法</h3><ol>
<li>includes方法返回一个布尔值，表示某个数组是否包含了某一个值。</li>
<li>我们之前学习的判断值是否在数组中使用的是indexOf()方法</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="string">&quot;苹果&quot;</span>,<span class="string">&quot;橘子&quot;</span>,<span class="string">&quot;香蕉&quot;</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr.<span class="title function_">includes</span>(<span class="string">&quot;橘子&quot;</span>))</span><br></pre></td></tr></table></figure>
<h3 id="find-和-findIndex方法"><a href="#find-和-findIndex方法" class="headerlink" title="find 和 findIndex方法"></a>find 和 findIndex方法</h3><ol>
<li>find方法的作用就是对数组的查找，查找的结果是找到符合的第一项为止，后面即便有多项符合也不找了</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>];</span><br><span class="line"><span class="keyword">var</span> result = arr.<span class="title function_">find</span>(<span class="keyword">function</span>(<span class="params">item</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> item &gt; <span class="number">2</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result)</span><br></pre></td></tr></table></figure>
<ol>
<li>数组实例的 findIndex 方法的用法与 find方法非常类似，返回第一个符合条件的数组成员的位置，如果所有成员都不符合条件，则返回-1。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> result2 = arr.<span class="title function_">findIndex</span>(<span class="keyword">function</span>(<span class="params">item</span>)&#123;</span><br><span class="line">      <span class="keyword">return</span> item &gt; <span class="number">2</span></span><br><span class="line">    &#125;)</span><br></pre></td></tr></table></figure>
<h3 id="Array-from方法"><a href="#Array-from方法" class="headerlink" title="Array.from方法"></a>Array.from方法</h3><ol>
<li>Array.from 方法用于将两类对象转为真正的数组：类似数组的对象（array-like object）和可遍历（iterable）的对象</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arrayLike = &#123;</span><br><span class="line">    <span class="string">&#x27;0&#x27;</span>: <span class="string">&#x27;a&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;1&#x27;</span>: <span class="string">&#x27;b&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;2&#x27;</span>: <span class="string">&#x27;c&#x27;</span>,</span><br><span class="line">    <span class="attr">length</span>: <span class="number">3</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr = <span class="title class_">Array</span>.<span class="title function_">from</span>(arrayLike)</span><br></pre></td></tr></table></figure>
<ol>
<li>实际应用中函数的arguments和DomList更常用这个方法</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">fun</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Array</span>.<span class="title function_">from</span>(<span class="variable language_">arguments</span>))</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">fun</span>(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>)</span><br></pre></td></tr></table></figure>
<h3 id="Array-of方法"><a href="#Array-of方法" class="headerlink" title="Array.of方法"></a>Array.of方法</h3><ol>
<li>Array.of方法用于将一组值，转换为数组。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Array</span>.<span class="title function_">of</span>(<span class="number">3</span>, <span class="number">11</span>, <span class="number">8</span>) <span class="comment">// [3,11,8]</span></span><br><span class="line"><span class="title class_">Array</span>.<span class="title function_">of</span>(<span class="number">3</span>) <span class="comment">// [3]</span></span><br><span class="line"><span class="title class_">Array</span>.<span class="title function_">of</span>(<span class="number">3</span>).<span class="property">length</span> <span class="comment">// 1</span></span><br></pre></td></tr></table></figure>
<h2 id="对象的扩展"><a href="#对象的扩展" class="headerlink" title="对象的扩展"></a>对象的扩展</h2><h3 id="对象可以省略v"><a href="#对象可以省略v" class="headerlink" title="对象可以省略v"></a>对象可以省略v</h3><ol>
<li>对象的表达是k:v，当对象的 k和v 相同的时候，可以省略v</li>
<li>看下面的例子</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">var</span> b = <span class="number">2</span>;</span><br><span class="line"><span class="keyword">var</span> c = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">a</span>: a,</span><br><span class="line">  <span class="attr">b</span>: b,</span><br><span class="line">  <span class="attr">c</span>: c</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的a，b，c都是有相同的k和v的所以可以简写为</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  a,</span><br><span class="line">  b,</span><br><span class="line">  c</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>所以我们就记住一个口诀，<code>kv一致省略v</code></li>
<li>这种省略v的写法很常见，工作中会遇到比如下面的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> result = (<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">var</span> s = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="number">100</span>; i++)&#123;</span><br><span class="line">    s += i</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> s</span><br><span class="line">&#125;)()</span><br><span class="line"><span class="comment">// 注意：kv一致省略v</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123;result&#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj)</span><br></pre></td></tr></table></figure>
<ol>
<li>需要注意的是省略v的时候k不能加引号<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;<span class="string">&quot;result&quot;</span>&#125;;</span><br></pre></td></tr></table></figure></li>
<li>上面的写法是错误的，不能加引号</li>
</ol>
<h3 id="对象的方法简写"><a href="#对象的方法简写" class="headerlink" title="对象的方法简写"></a>对象的方法简写</h3><ol>
<li>对象的方法也是可以简写的</li>
<li>先看简写之前的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  a : <span class="number">100</span>,</span><br><span class="line">  <span class="attr">fn</span>: <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">obj.<span class="title function_">fn</span>()</span><br></pre></td></tr></table></figure>
<ol>
<li>来看简写之后的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  a : <span class="number">200</span>,</span><br><span class="line">  <span class="title function_">fn</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>方法的 name 属性表示的是方法名称<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  a : <span class="number">200</span>,</span><br><span class="line">  <span class="title function_">fn</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="property">fn</span>.<span class="property">name</span>) <span class="comment">//fn</span></span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="Object-keys-和-Object-values"><a href="#Object-keys-和-Object-values" class="headerlink" title="Object.keys 和 Object.values"></a>Object.keys 和 Object.values</h3><ol>
<li>Object.keys 方法返回的是对象的键名数组；</li>
<li>Object.values 方法返回的是对象的值数组</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="string">&quot;name&quot;</span>:<span class="string">&quot;小明&quot;</span>,</span><br><span class="line">  <span class="string">&quot;age&quot;</span>: <span class="number">18</span>,</span><br><span class="line">  <span class="string">&quot;sex&quot;</span>: <span class="string">&quot;男&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> keyArr = <span class="title class_">Object</span>.<span class="title function_">keys</span>(obj)</span><br><span class="line"><span class="keyword">var</span> valueArr = <span class="title class_">Object</span>.<span class="title function_">values</span>(obj)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(keyArr,valueArr)</span><br></pre></td></tr></table></figure>
<h3 id="Object-is方法"><a href="#Object-is方法" class="headerlink" title="Object.is方法"></a>Object.is方法</h3><ol>
<li>我们之前学习判断两个值是否相等的时候使用的是<code>==或者===</code></li>
<li>它们都有自己的缺点，前者会自动转换数据类型，后者的NaN不自等，还有 +0会等于-0</li>
<li>JavaScript之前缺少一种实际的应用场景，就应该是如果值相等就会返回 true的结果</li>
<li>ES6提供了一个方法来解决这个问题</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">is</span>(<span class="title class_">NaN</span>,<span class="title class_">NaN</span>)); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">is</span>(+<span class="number">0</span>,-<span class="number">0</span>));	<span class="comment">// false</span></span><br></pre></td></tr></table></figure>
<ol>
<li>对于引用类型值还是按照是否是同一个地址来判断</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">is</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])) <span class="comment">// false</span></span><br></pre></td></tr></table></figure>
<ol>
<li>我们知道对象、数组等等是引用类型值，引用类型值的特点就是在内存中不是同一个地址，所以不自等。</li>
</ol>
<h3 id="Object-assign方法"><a href="#Object-assign方法" class="headerlink" title="Object.assign方法"></a>Object.assign方法</h3><ol>
<li>Object.assign方法用于对象的合并，将源对象（source）的所有可枚举属性，复制到目标对象方法用于对象的合并，将对象的可枚举属性复制到目标对象</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> o</span><br><span class="line">bj1 = &#123;<span class="attr">a</span>: <span class="number">1</span>, <span class="attr">b</span>: <span class="number">2</span>, <span class="attr">c</span>: <span class="number">3</span>&#125;;</span><br><span class="line"><span class="keyword">var</span> obj2 = &#123;<span class="attr">d</span>: <span class="number">4</span>, <span class="attr">e</span>: <span class="number">5</span>, <span class="attr">f</span>: <span class="number">6</span>&#125;;</span><br><span class="line"><span class="keyword">var</span> obj3 = &#123;<span class="attr">g</span>: <span class="number">7</span>, <span class="attr">h</span>: <span class="number">8</span>, <span class="attr">i</span>: <span class="number">9</span>&#125;;</span><br><span class="line"></span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">assign</span>(obj1,obj2,obj3);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj1)</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的结果其实是将obj2和obj3合并到了obj1的上面，此时obj1的对象本质上已经被改变了，如果不希望改变结果可以用下面的代码示例</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> result = <span class="title class_">Object</span>.<span class="title function_">assign</span>(&#123;&#125;,obj1,obj2,obj3);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result)</span><br></pre></td></tr></table></figure>
<ol>
<li>第一个对象就是合并源对象，所以Object.assign()可以有无限个参数，但是只会更改到第一个参数对象中</li>
<li>所以如果我们的业务场景是合并汇总，不更改原对象，就使用第二个示例，否则就可以使用第一个示例</li>
<li>由于undefined和null无法转成对象，所以如果它们作为参数，就会报错。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Object</span>.<span class="title function_">assign</span>(<span class="literal">undefined</span>) <span class="comment">// 报错</span></span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">assign</span>(<span class="literal">null</span>) <span class="comment">// 报错</span></span><br></pre></td></tr></table></figure>
<ol>
<li>Object.assign方法实行的是浅拷贝，而不是深拷贝。也就是说，如果源对象某个属性的值是对象，那么目标对象拷贝得到的是这个对象的引用。</li>
</ol>
<h3 id="对象中的动态键-方括号"><a href="#对象中的动态键-方括号" class="headerlink" title="对象中的动态键-方括号"></a>对象中的动态键-方括号</h3><ol>
<li>当对象的键名是一个变量的时候，在{}中可以用[]来包裹这个变量成为键的名字</li>
<li>看一个例子，比如我们遇到体能测试，如果是男生就测试单杠，如果是女就测试仰卧起坐，所以测试科目是不固定的，需要动态获取结果</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> sex = <span class="string">&quot;男&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(sex == <span class="string">&quot;男&quot;</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> k = <span class="string">&quot;dangang&quot;</span></span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">  <span class="keyword">var</span> k = <span class="string">&quot;yangwoqizuo&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小明&quot;</span>,</span><br><span class="line">  <span class="string">&quot;sex&quot;</span>: sex,</span><br><span class="line">  [k]: <span class="number">20</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>如果是男生</li>
<li>如果把sex改为女</li>
<li>注意，省略v的对象写法不能和动态键一起使用</li>
<li>下面的写法是错误的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> foo = <span class="string">&#x27;bar&#x27;</span>;</span><br><span class="line"><span class="keyword">var</span> bar = <span class="string">&#x27;abc&#x27;</span>;</span><br><span class="line"><span class="keyword">var</span> baz = &#123; [foo] &#125;;</span><br></pre></td></tr></table></figure>
<ol>
<li>正确的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> foo = <span class="string">&#x27;bar&#x27;</span>;</span><br><span class="line"><span class="keyword">var</span> baz = &#123; [foo]: <span class="string">&#x27;abc&#x27;</span>&#125;;</span><br></pre></td></tr></table></figure>
<h3 id="for…in方法"><a href="#for…in方法" class="headerlink" title="for…in方法"></a>for…in方法</h3><ol>
<li>循环遍历对象自身的和继承的可枚举属性（不含Symbol属性）。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span>  obj = &#123;<span class="attr">a</span>: <span class="number">1</span>, <span class="attr">b</span>: <span class="number">2</span>, <span class="attr">c</span>: <span class="number">3</span>&#125;;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> k <span class="keyword">in</span> obj) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(k,obj[k])&#125;</span><br></pre></td></tr></table></figure>
<h2 id="函数的扩展"><a href="#函数的扩展" class="headerlink" title="函数的扩展"></a>函数的扩展</h2><h3 id="箭头函数"><a href="#箭头函数" class="headerlink" title="箭头函数"></a>箭头函数</h3><ol>
<li>下面的例子就是一个的箭头函数，省略了function关键字，加了=&gt;运算符</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">sum</span> = (<span class="params">a,b</span>)=&gt;&#123;</span><br><span class="line">  <span class="keyword">return</span> a + b</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum</span>(<span class="number">2</span>,<span class="number">3</span>))</span><br></pre></td></tr></table></figure>
<ol>
<li>=&gt;是一个运算符，中间不能有空格</li>
<li>如果函数内部只有一行语句，可以省略{}和return</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">sum</span> = (<span class="params">a,b</span>) =&gt; a + b;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum</span>(<span class="number">5</span>,<span class="number">3</span>))</span><br></pre></td></tr></table></figure>
<ol>
<li>反之要加{}和return</li>
<li>箭头函数更重要的一点是可以连续箭头</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">fn</span> = (<span class="params">a,b</span>) =&gt; <span class="function">(<span class="params">m</span>)=&gt;</span> a+b+m;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fn</span>(<span class="number">1</span>,<span class="number">3</span>)(<span class="number">5</span>))</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的函数等价于下面的函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fn = <span class="keyword">function</span> (<span class="params">a,b</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">m</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> a + b + m</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="箭头函数的上下文"><a href="#箭头函数的上下文" class="headerlink" title="箭头函数的上下文"></a>箭头函数的上下文</h3><ol>
<li>箭头函数的上下文 this是函数体内的 this对象，就是定义时所在的对象，而不是调用时所在的对象。</li>
<li>我们看普通函数的上下文</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">100</span>;</span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">a</span>: <span class="number">20</span>,</span><br><span class="line">  <span class="attr">b</span>: <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">obj.<span class="title function_">b</span>() <span class="comment">// 20</span></span><br></pre></td></tr></table></figure>
<ol>
<li>你会发现普通函数的上下文是调用时候确定的，而不是定义时候确定的</li>
<li>箭头函数会在定义的时候确定自己的上下文</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> b = <span class="number">200</span>;</span><br><span class="line"><span class="keyword">var</span> obj2 = &#123;</span><br><span class="line">  <span class="attr">b</span>: <span class="number">10</span>,</span><br><span class="line">  <span class="attr">c</span>: <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">b</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj2.<span class="title function_">c</span>())  <span class="comment">// 200 虽然是对象打点调用的，但是由于是箭头函数，所以不是按照普通函数结果返回的，上下文是window对象</span></span><br></pre></td></tr></table></figure>
<ol>
<li>箭头函数的 call 和 apply是失效的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">obj2.<span class="property">c</span>.<span class="title function_">apply</span>(obj3) <span class="comment">// 200</span></span><br><span class="line">obj2.<span class="property">c</span>.<span class="title function_">call</span>(obj3) <span class="comment">// 200</span></span><br></pre></td></tr></table></figure>
<h3 id="bind方法"><a href="#bind方法" class="headerlink" title="bind方法"></a>bind方法</h3><ol>
<li>bind方法表示给一个函数定死上下文，无论如何调用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">fun</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">a</span>: <span class="number">100</span>,</span><br><span class="line">  <span class="attr">b</span>: <span class="number">200</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj2 = &#123;</span><br><span class="line">  <span class="attr">a</span>: <span class="number">123</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> fun2 = fun.<span class="title function_">bind</span>(obj);</span><br><span class="line"><span class="title function_">fun2</span>()</span><br><span class="line">fun2.<span class="title function_">call</span>(obj2)</span><br><span class="line">fun2.<span class="title function_">apply</span>(obj2)</span><br></pre></td></tr></table></figure>
<ol>
<li>此时 call 和 apply都是失效的</li>
<li>bind、call、apply的区别？<ol>
<li>bind不能调用函数，call和apply会调用函</li>
<li>bind会定死上下文，call和apply是临时上下文</li>
</ol>
</li>
</ol>
<h3 id="函数默认参数"><a href="#函数默认参数" class="headerlink" title="函数默认参数"></a>函数默认参数</h3><ol>
<li>函数可以有默认参数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">fun</span>(<span class="params">a,b=<span class="number">100</span></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> a + b;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fun</span>(<span class="number">2</span>)) <span class="comment">// 102</span></span><br></pre></td></tr></table></figure>
<ol>
<li>没有第二个参数使用默认参数，有第二个参数使用第二个参数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">fun</span>(<span class="params">a,b=<span class="number">100</span></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> a + b;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fun</span>(<span class="number">2</span>,<span class="number">5</span>)) <span class="comment">// 7</span></span><br></pre></td></tr></table></figure>
<ol>
<li>函数的默认值会导致函数的 length属性获取不到该默认值</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">(<span class="keyword">function</span> (<span class="params">a = <span class="number">0</span>, b, c</span>) &#123;&#125;).<span class="property">length</span> <span class="comment">// 0</span></span><br><span class="line">(<span class="keyword">function</span> (<span class="params">a, b = <span class="number">1</span>, c</span>) &#123;&#125;).<span class="property">length</span> <span class="comment">// 1</span></span><br></pre></td></tr></table></figure>
<h3 id="箭头函数不绑定-arguments参数"><a href="#箭头函数不绑定-arguments参数" class="headerlink" title="箭头函数不绑定 arguments参数"></a>箭头函数不绑定 arguments参数</h3><ol>
<li>普通函数是有 arguments对象的，但是箭头函数是没有 arguments对象的</li>
<li>先来看普通函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fun = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">arguments</span>) <span class="comment">// 实参列表返回的类数组对象</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">fun</span>(<span class="number">11</span>,<span class="number">22</span>,<span class="number">33</span>,<span class="number">44</span>,<span class="number">55</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>再来看箭头函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">fun2</span> = (<span class="params"></span>)=&gt;&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">arguments</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">fun2</span>(<span class="number">11</span>,<span class="number">22</span>,<span class="number">33</span>,<span class="number">44</span>,<span class="number">55</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>通过上面的错误你会发现箭头函数本身就没有绑定 arguments这个对象，如果我们想要有 arguments的替代者我们可以使用 rest参数来代替</li>
</ol>
<h3 id="…rest参数"><a href="#…rest参数" class="headerlink" title="…rest参数"></a>…rest参数</h3><ol>
<li>ES6引入rest参数（形式为“…变量名”），用于获取函数的多余参数，这样就不需要使用arguments对象了</li>
<li>…我们可以叫做扩展运算法</li>
<li>函数的<code>…rest参数</code>指的就是…运算符进行对参数的“解构方式”，<code>专业术语叫做函数的…rest参数</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">fun2</span> = (<span class="params">...arg</span>)=&gt;&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(arg)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">fun2</span>(<span class="number">11</span>,<span class="number">22</span>,<span class="number">33</span>,<span class="number">44</span>,<span class="number">55</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>rest参数 将所有实参整合为了一个数组</li>
<li>注意：rest参数必须在函数形参列表的最后一位</li>
<li>下面的写法是错误的…b的后面有c是不合法的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 报错</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">f</span>(<span class="params">a, ...b, c</span>) &#123;</span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>函数的 length指的是形参列表，但是 rest参数不会包含在形参列表中</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(<span class="keyword">function</span>(<span class="params">a</span>) &#123;&#125;).<span class="property">length</span>  <span class="comment">// 1</span></span><br><span class="line">(<span class="keyword">function</span>(<span class="params">...a</span>) &#123;&#125;).<span class="property">length</span>  <span class="comment">// 0</span></span><br><span class="line">(<span class="keyword">function</span>(<span class="params">a, ...b</span>) &#123;&#125;).<span class="property">length</span>  <span class="comment">// 1</span></span><br></pre></td></tr></table></figure>
<h3 id="箭头函数不可以当做构造函数"><a href="#箭头函数不可以当做构造函数" class="headerlink" title="箭头函数不可以当做构造函数"></a>箭头函数不可以当做构造函数</h3><ol>
<li>普通函数使用new 关键字来创建构造函数，但是箭头函数是一个匿名函数不能使用new 来创建构造函数，主要是因为箭头函数的上下文的问题导致设计时候就没有constructor</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="title function_">Fun</span> = (<span class="params"></span>)=&gt;&#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">a</span> = <span class="number">100</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> aa = <span class="keyword">new</span> <span class="title class_">Fun</span>()</span><br></pre></td></tr></table></figure>
<h3 id="箭头函数没有原型属性-prototype"><a href="#箭头函数没有原型属性-prototype" class="headerlink" title="箭头函数没有原型属性 prototype"></a>箭头函数没有原型属性 prototype</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">fun</span> = (<span class="params"></span>)=&gt;&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="number">100</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fun.<span class="property"><span class="keyword">prototype</span></span>) <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure>
<h3 id="箭头函数不能进行变量声明提升"><a href="#箭头函数不能进行变量声明提升" class="headerlink" title="箭头函数不能进行变量声明提升"></a>箭头函数不能进行变量声明提升</h3><ol>
<li>箭头函数没有变量声明提升本身是定义性质所导致的，是因为声明的方法必须是var、const、let这些关键字定义的，这些方式定义的无论是普通函数还是箭头函数都不允许先使用后定义</li>
<li>先来看普通函数的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fun</span>(<span class="number">1</span>,<span class="number">2</span>))</span><br><span class="line"><span class="keyword">var</span> fun = <span class="keyword">function</span>(<span class="params">a,b</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> a +b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>再来看箭头函数的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fun2</span>(<span class="number">1</span>,<span class="number">2</span>))</span><br><span class="line"><span class="keyword">var</span> <span class="title function_">fun2</span> = (<span class="params">a,b</span>)=&gt; &#123;</span><br><span class="line">  <span class="keyword">return</span> a +b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>函数可以先使用后定义的是 function 关键字定义的函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fn</span>(<span class="number">1</span>,<span class="number">2</span>))</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn</span>(<span class="params">a,b</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> a +b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="函数的参数也可以进行解构"><a href="#函数的参数也可以进行解构" class="headerlink" title="函数的参数也可以进行解构"></a>函数的参数也可以进行解构</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">&#123;x, y = <span class="number">5</span>&#125;</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(x, y);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>(&#123;<span class="attr">x</span>: <span class="number">1</span>, <span class="attr">y</span>: <span class="number">2</span>&#125;) <span class="comment">// 1, 2</span></span><br></pre></td></tr></table></figure>
<h3 id="严格模式"><a href="#严格模式" class="headerlink" title="严格模式"></a>严格模式</h3><ol>
<li>JavaScript的严格模式使用业务场景比较少，需要了解JavaScript严格模式的</li>
<li>建议参考文章地址<a target="_blank" rel="noopener" href="https://www.runoob.com/js/js-strict.html，">https://www.runoob.com/js/js-strict.html，</a></li>
<li>结合我们ES6函数扩展的严格模式进行学习<a target="_blank" rel="noopener" href="http://caibaojian.com/es6/function.html">http://caibaojian.com/es6/function.html</a></li>
</ol>
<h3 id="箭头函数上下文的小练习"><a href="#箭头函数上下文的小练习" class="headerlink" title="箭头函数上下文的小练习"></a>箭头函数上下文的小练习</h3><ol>
<li>箭头函数有几个使用注意点。<ol>
<li>函数体内的 <code>this对象</code>，就是定义时所在的对象，而不是使用时所在的对象。</li>
<li>不可以当作构造函数，也就是说，不可以使用<code>new命令</code>，否则会抛出一个错误。</li>
<li>不可以使用<code>arguments对象</code>，该对象在函数体内不存在。如果要用，<code>可以用Rest参数代替</code>。</li>
<li>不可以使用<code>yield命令</code>，因此箭头函数不能用作<code>Generator函数</code>。</li>
</ol>
</li>
<li>普通函数的上下文是调用使用才能确定的，并且规则很多，但是箭头函数的上下文是定义时候确定的。规则其实很简单，只要理解了，就能应对</li>
</ol>
<h4 id="题目1："><a href="#题目1：" class="headerlink" title="题目1："></a>题目1：</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">window</span>.<span class="property">color</span> = <span class="string">&quot;purple&quot;</span></span><br><span class="line"><span class="keyword">let</span> color = <span class="string">&quot;green&quot;</span>;</span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  <span class="attr">color</span>: <span class="string">&quot;blue&quot;</span>,</span><br><span class="line">  <span class="attr">getColor</span>:<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">color</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> <span class="title function_">sayColor</span> = (<span class="params"></span>)=&gt;&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">color</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="title function_">getColor</span>()) <span class="comment">// purple</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sayColor</span>())<span class="comment">// purple</span></span><br></pre></td></tr></table></figure>
<ol>
<li>解析：obj对象中的getColor 函数定义时候所处的位置是obj对象中，obj.a是blue，但是obj不是函数，</li>
<li>所以getColor内部的this不会主动去找obj.color，继续向上找上下文，没找到就输出window的color为purple；sayColor方法父作用域也是window所以输出purple</li>
</ol>
<h4 id="题目2："><a href="#题目2：" class="headerlink" title="题目2："></a>题目2：</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">200</span>;</span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">a</span>: <span class="number">100</span>,</span><br><span class="line">  <span class="attr">fn</span>: <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function">()=&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">a</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj2 = &#123;</span><br><span class="line">  <span class="attr">a</span>: <span class="number">300</span>,</span><br><span class="line">  <span class="attr">fn</span>: obj.<span class="property">fn</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> fn = obj2.<span class="title function_">fn</span>()</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">fn</span>()) <span class="comment">// 300</span></span><br></pre></td></tr></table></figure>
<ol>
<li>解析：答案是300，因为obj对象内部的箭头函数定义在obj对象中的fn普通函数中，</li>
<li>因为普通函数的上下文this必须在调用的时候才能确定，所以最后obj2在调用fn函数，obj2的上下文是300，所以箭头函数的父亲的上下文就是300，所以箭头函数的上下文就是300</li>
</ol>
<h4 id="题目3："><a href="#题目3：" class="headerlink" title="题目3："></a>题目3：</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="built_in">setTimeout</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">a</span>)</span><br><span class="line">  &#125;,<span class="number">100</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line">foo.<span class="title function_">call</span>(&#123;<span class="attr">a</span>: <span class="number">20</span>&#125;) <span class="comment">//20</span></span><br></pre></td></tr></table></figure>
<ol>
<li>解析：</li>
<li>箭头函数内部输出的a定义在foo普通函数中，又因为foo普通函数调用的时候call了上下文将一个对象{a:20}指给了foo函数，所以foo函数的上下文就是这个对象，foo.a 就是20，所以箭头函数的this.a也是20</li>
<li><code>建议同学们也看一下es6文档中函数的上下文的小题目，补充一下知识</code></li>
</ol>
<h2 id="class类的增加"><a href="#class类的增加" class="headerlink" title="class类的增加"></a>class类的增加</h2><h3 id="定义“类”"><a href="#定义“类”" class="headerlink" title="定义“类”"></a>定义“类”</h3><ol>
<li><p>之前我们都是使用<code>new function</code>来定义一个函数的类型，现在我们可以使用class关键字来定义一个函数类</p>
<p>先来看普通函数定义的类</p>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">People</span>(<span class="params">name,age,sex</span>)&#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title class_">People</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">singsong</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`我是<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>，今年<span class="subst">$&#123;<span class="variable language_">this</span>.age&#125;</span>岁了，我在唱歌`</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">People</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">game</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;玩游戏&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> xiaoming = <span class="keyword">new</span> <span class="title class_">People</span>(<span class="string">&quot;小明&quot;</span>,<span class="number">18</span>,<span class="string">&quot;男&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(xiaoming)</span><br></pre></td></tr></table></figure>
<ol>
<li>我们看 class定义的类</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">People</span>&#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name,age,sex</span>)&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">singsong</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`我是<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>，今年<span class="subst">$&#123;<span class="variable language_">this</span>.age&#125;</span>岁了，我在唱歌`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">game</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;玩游戏&quot;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> xiaohong = <span class="keyword">new</span> <span class="title class_">People</span>(<span class="string">&quot;小红&quot;</span>,<span class="number">17</span>,<span class="string">&quot;女&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(xiaohong)</span><br></pre></td></tr></table></figure>
<ol>
<li>要注意的是class 类语法的问题，参考 C# 中类的语法</li>
<li>虽然 es6增加了class关键字，但是JavaScript中还是没有类的概念！</li>
<li>依然是基于面向对象，而不是真正的面向对象，基于原型链来模型实现class，机理和普通函数定义的类是一样的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(xiaohong.<span class="property">singsong</span> === <span class="title class_">People</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">singsong</span>) <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(xiaohong.<span class="title function_">hasOwnProperty</span>(<span class="string">&quot;singsong&quot;</span>)) <span class="comment">// false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(xiaohong.<span class="title function_">hasOwnProperty</span>(<span class="string">&quot;name&quot;</span>)) <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/11/09/zSK3HH.png" alt=""></p>
<h3 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h3><ol>
<li>看一普通函数的继承</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">People</span>(<span class="params">name,age,sex</span>)&#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title class_">People</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">singsong</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`我是<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>，今年<span class="subst">$&#123;<span class="variable language_">this</span>.age&#125;</span>岁了，我在唱歌`</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title class_">People</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">game</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;玩游戏&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Student</span>(<span class="params">name,age,sex,id,school</span>)&#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">id</span> = id;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">school</span> = school;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span> = <span class="keyword">new</span> <span class="title class_">People</span>() <span class="comment">// 继承:使用原型链去查找的原理</span></span><br><span class="line"></span><br><span class="line"><span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">test</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>在考试`</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> xiaohong = <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&quot;小红&quot;</span>,<span class="number">12</span>,<span class="string">&quot;女&quot;</span>,<span class="string">&quot;10001&quot;</span>,<span class="string">&quot;第二中学&quot;</span>)</span><br><span class="line">xiaohong.<span class="title function_">test</span>()</span><br><span class="line">xiaohong.<span class="title function_">singsong</span>()</span><br></pre></td></tr></table></figure>
<ol>
<li>看一下继承的原理</li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/11/09/zSKJUA.png" alt=""></p>
<ol>
<li>看一下ES6是如何实现继承的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">People</span>&#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name,age,sex</span>)&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">singsong</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`我是<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>，今年<span class="subst">$&#123;<span class="variable language_">this</span>.age&#125;</span>岁了，我在唱歌`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">game</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;玩游戏&quot;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// extends 继承自 People，super方法会自动去找继承的属性</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span> <span class="keyword">extends</span> <span class="title class_ inherited__">People</span>&#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name,age,sex,id,school</span>) &#123;</span><br><span class="line">    <span class="comment">// super方法会自动去找继承的属性</span></span><br><span class="line">    <span class="variable language_">super</span>(name,age,sex) <span class="comment">// 调用的是超类的构造器</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">id</span> = id;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">school</span> = school;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">test</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>在考试`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> xiaohong = <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&quot;小红&quot;</span>,<span class="number">12</span>,<span class="string">&quot;女&quot;</span>,<span class="string">&quot;10001&quot;</span>,<span class="string">&quot;第二中学&quot;</span>)</span><br><span class="line">xiaohong.<span class="title function_">test</span>()</span><br><span class="line">xiaohong.<span class="title function_">singsong</span>()</span><br></pre></td></tr></table></figure>
<ol>
<li>es6利用extends来实现继承</li>
</ol>
<h3 id="constructor方法"><a href="#constructor方法" class="headerlink" title="constructor方法"></a>constructor方法</h3><ol>
<li>constructor方法是类的默认方法，</li>
<li>通过new命令生成对象实例时，自动调用该方法。一个类必须有constructor方法，如果没有显式定义，一个空的constructor方法会被默认添加。</li>
<li>class定义的构造函数，必须使用new关键字调用，否则会报错</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Foo</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="title class_">Object</span>.<span class="title function_">create</span>(<span class="literal">null</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title class_">Foo</span>()</span><br></pre></td></tr></table></figure>
<h3 id="class类定义的构造函数没有变量声明的提升"><a href="#class类定义的构造函数没有变量声明的提升" class="headerlink" title="class类定义的构造函数没有变量声明的提升"></a>class类定义的构造函数没有变量声明的提升</h3><ol>
<li>什么是声明提升？我们先看普通函数创建的构造函数执行</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaoming = <span class="keyword">new</span> <span class="title class_">People</span>(<span class="string">&quot;小明&quot;</span>,<span class="number">19</span>,<span class="string">&quot;男&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(xiaoming);</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">People</span>(<span class="params">name,age,sex</span>)&#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>再来看class定义的构造函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaohong = <span class="keyword">new</span> <span class="title class_">People</span>(<span class="string">&quot;小红&quot;</span>,<span class="number">18</span>,<span class="string">&quot;女&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(xiahong);</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">People</span>&#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name,age,sex</span>)&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="继承的构造函数必须要在constructor中调用super否则会报错"><a href="#继承的构造函数必须要在constructor中调用super否则会报错" class="headerlink" title="继承的构造函数必须要在constructor中调用super否则会报错"></a>继承的构造函数必须要在constructor中调用super否则会报错</h3><ol>
<li>看下面的代码</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Point</span> &#123; <span class="comment">/* ... */</span> &#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ColorPoint</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Point</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">   <span class="comment">//内部没有调用super</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> cp = <span class="keyword">new</span> <span class="title class_">ColorPoint</span>();</span><br></pre></td></tr></table></figure>
<ol>
<li>继承的子类可以不用写constructor，但是不代表没有定义，系统会自动悄悄的给你加上下面的代码</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">constructor</span>(<span class="params">...args</span>) &#123;</span><br><span class="line">  <span class="variable language_">super</span>(...args);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>继承的子类使用this之前必须要先调用super后再定义</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Point</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">x, y</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">x</span> = x;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">y</span> = y;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ColorPoint</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Point</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">x, y, color,name</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">name</span> = name; <span class="comment">// ReferenceError</span></span><br><span class="line">    <span class="variable language_">super</span>(x, y);</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">color</span> = color; <span class="comment">// 正确</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> aa = <span class="keyword">new</span> <span class="title class_">ColorPoint</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(aa)</span><br></pre></td></tr></table></figure>
<h3 id="Object-getPrototypeOf方法"><a href="#Object-getPrototypeOf方法" class="headerlink" title="Object.getPrototypeOf方法"></a>Object.getPrototypeOf方法</h3><ol>
<li>Object.getPrototypeOf()方法用来查询当前的子类的父亲</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">People</span>&#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name,age,sex</span>)&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">singsong</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`我是<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>，今年<span class="subst">$&#123;<span class="variable language_">this</span>.age&#125;</span>岁了，我在唱歌`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">game</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;玩游戏&quot;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span> <span class="keyword">extends</span> <span class="title class_ inherited__">People</span>&#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name,age,sex,id,school</span>) &#123;</span><br><span class="line">    <span class="variable language_">super</span>(name,age,sex)</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">id</span> = id;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">school</span> = school;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">test</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>在考试`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> xiaohong = <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&quot;小红&quot;</span>,<span class="number">12</span>,<span class="string">&quot;女&quot;</span>,<span class="string">&quot;10001&quot;</span>,<span class="string">&quot;第二中学&quot;</span>)</span><br><span class="line">xiaohong.<span class="title function_">test</span>()</span><br><span class="line">xiaohong.<span class="title function_">singsong</span>()</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">getPrototypeOf</span>(<span class="title class_">Student</span>) == <span class="title class_">People</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">getPrototypeOf</span>(<span class="title class_">Student</span>));</span><br></pre></td></tr></table></figure>
<h3 id="super关键字"><a href="#super关键字" class="headerlink" title="super关键字"></a>super关键字</h3><ol>
<li>super这个关键字，既可以当作函数使用，也可以当作对象使用</li>
<li>先看当做函数使用的场景</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;我是A的constructor&quot;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span> <span class="keyword">extends</span> <span class="title class_ inherited__">A</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">super</span>();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> b = <span class="keyword">new</span> <span class="title function_">B</span>()</span><br></pre></td></tr></table></figure>
<ol>
<li>虽然super当做函数调用的时候，调用的是父函数的constructor构造器，但是上下文还是子类的自己的上下文</li>
<li>我们先看一下new.target</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">new</span>.<span class="property">target</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">new</span>.<span class="property">target</span>.<span class="property">name</span>) <span class="comment">// A</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">new</span> <span class="title function_">A</span>()</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">new</span>.<span class="property">target</span>.<span class="property">name</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span> <span class="keyword">extends</span> <span class="title class_ inherited__">A</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">super</span>();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">new</span> <span class="title function_">A</span>() <span class="comment">// A</span></span><br><span class="line"><span class="keyword">new</span> <span class="title function_">B</span>() <span class="comment">// B</span></span><br></pre></td></tr></table></figure>
<ol>
<li>super作为函数使用的时候只能子类的constructor构造器中，在其他的函数中会报错</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span> <span class="keyword">extends</span> <span class="title class_ inherited__">A</span> &#123;</span><br><span class="line">  <span class="title function_">m</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">super</span>(); <span class="comment">// 报错</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>super方法作为对象的时候，指向父类的原型对象。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> &#123;</span><br><span class="line">  <span class="title function_">p</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">2</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span> <span class="keyword">extends</span> <span class="title class_ inherited__">A</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">super</span>();</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">super</span>.<span class="title function_">p</span>()); <span class="comment">// 2</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> b = <span class="keyword">new</span> <span class="title function_">B</span>();</span><br></pre></td></tr></table></figure>
<h3 id="函数的get和set关键字"><a href="#函数的get和set关键字" class="headerlink" title="函数的get和set关键字"></a>函数的get和set关键字</h3><ol>
<li>与ES5一样，在Class内部可以使用get和set关键字，对某个属性设置存值函数和取值函数，拦截该属性的存取行为</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyClass</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">get</span> <span class="title function_">prop</span>() &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&#x27;getter&#x27;</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">set</span> <span class="title function_">prop</span>(<span class="params">value</span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;setter: &#x27;</span>+value);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> inst = <span class="keyword">new</span> <span class="title class_">MyClass</span>();</span><br><span class="line"></span><br><span class="line">inst.<span class="property">prop</span> = <span class="number">123</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(inst.<span class="property">prop</span>)</span><br></pre></td></tr></table></figure>
<h3 id="静态方法"><a href="#静态方法" class="headerlink" title="静态方法"></a>静态方法</h3><ol>
<li>类相当于实例的原型，所有在类中定义的方法，都会被实例继承。如果在一个方法前加上static关键字，就表示该方法不会被实例继承，而是直接通过类来调用，这就称为“静态方法”。</li>
<li>先看一下静态化之前的构造函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Foo</span> &#123;</span><br><span class="line">  <span class="title function_">classMethod</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;静态函数&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="string">&#x27;hello&#x27;</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Foo</span>.<span class="property">classMethod</span>) <span class="comment">//undefined</span></span><br></pre></td></tr></table></figure>
<ol>
<li>此时加了static关键字后</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Foo</span> &#123;</span><br><span class="line">  <span class="keyword">static</span> <span class="title function_">classMethod</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&#x27;hello&#x27;</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Foo</span>.<span class="property">classMethod</span>) <span class="comment">// 返回classMethod函数体</span></span><br><span class="line"><span class="title class_">Foo</span>.<span class="title function_">classMethod</span>() <span class="comment">// &#x27;hello&#x27;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>此时如果使用new产生实例后</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> foo = <span class="keyword">new</span> <span class="title class_">Foo</span>();</span><br><span class="line">foo.<span class="title function_">classMethod</span>()</span><br></pre></td></tr></table></figure>
<h3 id="new-target属性"><a href="#new-target属性" class="headerlink" title="new.target属性"></a>new.target属性</h3><ol>
<li>ES6为new命令引入了一个new.target属性，（在构造函数中）返回new命令作用于的那个构造函数。</li>
<li>如果构造函数不是通过new命令调用的，new.target会返回undefined，因此这个属性可以用来确定构造函数是怎么调用的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params">name</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">new</span>.<span class="property">target</span> !== <span class="literal">undefined</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">&#x27;必须使用new生成实例&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> xiaohong =  <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&quot;小红&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(xiaohong); <span class="comment">// 小红</span></span><br><span class="line"><span class="title class_">Person</span>(<span class="string">&quot;xiaoming&quot;</span>)</span><br></pre></td></tr></table></figure>
<h2 id="babel的基本使用"><a href="#babel的基本使用" class="headerlink" title="babel的基本使用"></a>babel的基本使用</h2><ol>
<li>bael是一个nodejs的工作流工具，babel工具的作用就是将es的新语法翻译为老的语法</li>
<li>babel的官网：<a target="_blank" rel="noopener" href="https://www.babeljs.cn/">https://www.babeljs.cn/</a></li>
<li>如何进行安装？</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install -g babel-cli</span><br></pre></td></tr></table></figure>
<ol>
<li>cli 表示command line interface（命令行接口），也就是使用CMD调用这个命令</li>
<li>以后我们会接触大量的工具，多数都是**-cli</li>
<li>安装完毕之后我们此时可以写一个dome</li>
<li>此时我们创建一个01.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a,b,c] = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br></pre></td></tr></table></figure>
<ol>
<li>此时由于我们安装了babel-cli，就可以进行babel的使用</li>
<li>输入命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">babel 01.js -o 001.js</span><br></pre></td></tr></table></figure>
<ol>
<li>此时会自动创建一个001.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a, b, c] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];</span><br></pre></td></tr></table></figure>
<ol>
<li>你会发现此时001.js文件内部的代码没有被翻译为老的语法</li>
<li>那是因为我们没有告诉 babel如何翻译？</li>
<li>此时我们需要安装依赖</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cnpm init</span><br><span class="line">cnpm install --save-dev babel-preset-env</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们还需要创建一个.babelrc的指导文件</li>
<li>文件内部</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">presets</span>: [<span class="string">&quot;env&quot;</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们就可以进行babel 01.js -o 001.js操作了</li>
<li>可以看下，已经翻译成功了</li>
<li>总结：<ol>
<li>babel是一个翻译工具，可以将高级的ES语法翻译为低端语法</li>
<li>babel需要-g安装babel-cli</li>
<li>babel的运行需要.babelrc文件进行指导</li>
<li>还需要安装依赖babel-preset-env</li>
<li>输入命令babel 目标文件 -o 新文件</li>
</ol>
</li>
</ol>
<h2 id="Promise对象（★）"><a href="#Promise对象（★）" class="headerlink" title="Promise对象（★）"></a>Promise对象（★）</h2><h3 id="Promise的含义"><a href="#Promise的含义" class="headerlink" title="Promise的含义"></a>Promise的含义</h3><ol>
<li>Promise 是异步编程的一种解决方案，比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现，ES6将其写进了语言标准，统一了用法，原生提供了 <code>Promise对象</code>。</li>
<li>所谓 Promise，简单说就是一个容器，里面保存着某个未来才会结束的事件（通常是一个异步操作）的结果。</li>
<li>从语法上说，Promise是一个对象，从它可以<code>获取异步操作的消息</code>。</li>
<li>Promise提供统一的 API，<code>各种异步操作都可以用同样的方法进行处理对象的状态不受外界影响</code>。</li>
<li>Promise对象代表一个异步操作，有三种状态：<code>Pending（进行中）、Resolved（已完成，又称Fulfilled）和 Rejected（已失败）</code>。</li>
<li>只有异步操作的结果，可以决定当前是哪一种状态，任何其他操作都无法改变这个状态。</li>
<li><code>这也是 Promise这个名字的由来，它的英语意思就是 “承诺”，表示其他手段无法改变</code>。</li>
<li>一旦状态改变，就不会再变，任何时候都可以得到这个结果。</li>
<li>Promise对象的状态改变，只有两种可能：</li>
<li>从 <code>Pending</code> 变为 <code>Resolved</code> 和从 <code>Pending</code> 变为 <code>Rejected</code>。只要这两种情况发生，状态就凝固了，不会再变了，会一直保持这个结果。<code>就算改变已经发生了，你再对 Promise对象添加回调函数，也会立即得到这个结果</code>。</li>
<li>这与事件（Event）完全不同，事件的特点是，如果你错过了它，再去监听，是得不到结果的</li>
<li>Promise 也有一些缺点。<ol>
<li>首先，无法取消 Promise，一旦新建它就会立即执行，无法中途取消。</li>
<li>其次，如果不设置回调函数，Promise 内部抛出的错误，不会反应到外部。</li>
<li>第三，当处于 Pending状态时，无法得知目前进展到哪一个阶段（刚刚开始还是即将完成）</li>
</ol>
</li>
<li>Promise对象 主要功能是解决异步的回调问题</li>
</ol>
<h3 id="复习异步和同步"><a href="#复习异步和同步" class="headerlink" title="复习异步和同步"></a>复习异步和同步</h3><ol>
<li>当cpu面对一个长时间、其他设备处理，比如磁盘I/O，数据库查询、写入等等这些操作的时候，此时有两种模式：第一种是同步模式，死等这个设备处理完成，此时cpu被堵塞了；第二种就是异步模式，不等这个设备处理完成，而是先执行后面的语句，等这个设备处理完成之后执行回调函数。</li>
<li>比如下面的代码，先让 cpu 处理累加计算的逻辑，然后再命令硬盘异步读取文件，此时读取过程中没有堵塞进程，cpu提前执行后面的累加程序，等读取完毕之后再执行读取内部的回调函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 0-100的累加</span></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>,sum = <span class="number">0</span>; i &lt;= <span class="number">100</span>; i++) &#123;</span><br><span class="line">  sum += i;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(sum);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 读取文件</span></span><br><span class="line">fs.<span class="title function_">readFile</span>(<span class="string">&quot;./txt/01.txt&quot;</span>,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 0-100的累加</span></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>,sum = <span class="number">0</span>; i &lt;= <span class="number">100</span>; i++) &#123;</span><br><span class="line">  sum += i;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(sum);</span><br></pre></td></tr></table></figure>
<ol>
<li>此时如果我们将代码改为同步的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 0-100的累加</span></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>,sum = <span class="number">0</span>; i &lt;= <span class="number">100</span>; i++) &#123;</span><br><span class="line">  sum += i;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(sum);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 同步读取文件</span></span><br><span class="line"><span class="keyword">var</span> content = fs.<span class="title function_">readFileSync</span>(<span class="string">&quot;./txt/01.txt&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(content.<span class="title function_">toString</span>())</span><br><span class="line"><span class="comment">// 0-100的累加</span></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>,sum = <span class="number">0</span>; i &lt;= <span class="number">100</span>; i++) &#123;</span><br><span class="line">  sum += i;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(sum);</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们发现，同步和异步的区别从语法上看，同步是在等号左侧接收，异步是在回调函数内部接收结果</li>
<li>除了语法层面上不同之外，时间上也有区别，同步代码的时间，会比异步代码的耗费时间要长</li>
</ol>
<h3 id="异步的语法缺点"><a href="#异步的语法缺点" class="headerlink" title="异步的语法缺点"></a>异步的语法缺点</h3><ol>
<li>第一个缺点就是异步代码的语法上会让代码变得不美观</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">fs.<span class="title function_">readFile</span>(<span class="string">&quot;./txt/01.txt&quot;</span>,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">  fs.<span class="title function_">readFile</span>(<span class="string">&quot;./txt/02.txt&quot;</span>,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(content.<span class="title function_">toString</span>());</span><br><span class="line">    fs.<span class="title function_">readFile</span>(<span class="string">&quot;./txt/03.txt&quot;</span>,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(content.<span class="title function_">toString</span>());</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>此时如果我们改成同步的，的确就美观了，此时我们也会发现cpu的效率变低了</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fs.<span class="title function_">readFileSync</span>(<span class="string">&quot;./txt/01.txt&quot;</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fs.<span class="title function_">readFileSync</span>(<span class="string">&quot;./txt/02.txt&quot;</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fs.<span class="title function_">readFileSync</span>(<span class="string">&quot;./txt/03.txt&quot;</span>));</span><br></pre></td></tr></table></figure>
<ol>
<li>第二个缺点就是异步的语法造成了，代码的维护性和机构性不强</li>
<li>我们可以使用 promise来解决这个问题</li>
</ol>
<h3 id="Promise的基本使用"><a href="#Promise的基本使用" class="headerlink" title="Promise的基本使用"></a>Promise的基本使用</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">rFile</span>(<span class="params">url</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(url,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">      <span class="keyword">if</span>(err) &#123;</span><br><span class="line">        <span class="title function_">reject</span>(err)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="title function_">resolve</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">rFile</span>(<span class="string">&quot;./txt/01.txt&quot;</span>).<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">rFile</span>(<span class="string">&quot;./txt/02.txt&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line">.<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">rFile</span>(<span class="string">&quot;./txt/03.txt&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line">.<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>上面代码中的红色部分就是用来处理我们的回调逻辑的部分</li>
<li>我们再来看Promise的封装</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">rFile</span>(<span class="params">url</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(url,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">      <span class="keyword">if</span>(err) &#123;</span><br><span class="line">        <span class="title function_">reject</span>(err)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="title function_">resolve</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>rFile函数返回了一个Promise的对象，这个对象就是构造函数，是ES6新增的</li>
<li>Promise一定是某一个函数的返回值，Promise必须当做一个函数的返回值才有意义，上面代码中Promise就是rFile函数的返回值</li>
<li>Promise在被 new 的时候要求传入一个函数，这个函数就是 Promise 的回调函数，这个函数有两个形参，分别是 resolve 和 reject</li>
<li>resolve 表示成功之后做的事情，reject 表示失败之后做的事情</li>
</ol>
<ol>
<li>下面代码中 then 的部分表示的就是读取成功之后的操作，catch 表示的是读取失败的操作</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">rFile</span>(<span class="string">&quot;./txt/011.txt&quot;</span>)</span><br><span class="line">.<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data)</span><br><span class="line">&#125;).<span class="title function_">catch</span>(<span class="function"><span class="params">err</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;读取错误&quot;</span>,err);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>下面的catch一旦遇到了错误就会阻止整个程序的执行，比如读取两个文件，第一个文件读取失败了</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">rFile</span>(<span class="string">&quot;./txt/011.txt&quot;</span>).<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">rFile</span>(<span class="string">&quot;./txt/02.txt&quot;</span>)</span><br><span class="line">&#125;).<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">123</span>)</span><br><span class="line">&#125;).<span class="title function_">catch</span>(<span class="function"><span class="params">err</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;读取错误&quot;</span>,err);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>上面代码中，你会发现由于没有011.txt，所以会走 catch，此时你会发现第二个 then中 123也没有输出</li>
<li>如果想要输出第二个 then 中的 data可以使用单个 then报错的方式，第二个参数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">rFile</span>(<span class="string">&quot;./txt/011.txt&quot;</span>).<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">rFile</span>(<span class="string">&quot;./txt/02.txt&quot;</span>)</span><br><span class="line">&#125;,<span class="function">(<span class="params">err</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;读取错误1&quot;</span>,err);</span><br><span class="line">&#125;).<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">123</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>上的代码中虽然011.txt没有抛出错误了，但是没有阻止下一个then的执行，输出了123</li>
</ol>
<blockquote>
<ol>
<li>Promise函数中，内部的语句一定是异步语句，异步语句的成功将通过resolve（成功的数据）传出去，</li>
<li>这个数据将成为后面调用的 then 函数中的 data 返回值，异步语句的失败将通过 reject（失败的数据）传出去，</li>
<li>这个数据将成为后面调用的 catch 函数中的 err 返回值，失败的语句也可以是then的第二个参数</li>
<li>Promise的实例拥有 then 的能力，then 里面接收一个参数，data 就是创建 promise的时候的 resolve；then进行连续打点</li>
</ol>
</blockquote>
<ol>
<li>then方法返回的是一个新的 Promise实例（注意，不是原来那个Promise实例）。因此可以采用链式写法，即 then方法后面再调用另一个 then 方法</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">rFile</span>(<span class="string">&quot;./txt/01.txt&quot;</span>).<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">rFile</span>(<span class="string">&quot;./txt/02.txt&quot;</span>)</span><br><span class="line">&#125;).<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data)</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">rFile</span>(<span class="string">&quot;./txt/03.txt&quot;</span>)</span><br><span class="line">&#125;).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h3 id="非Node环境使用Promise"><a href="#非Node环境使用Promise" class="headerlink" title="非Node环境使用Promise"></a>非Node环境使用Promise</h3><ol>
<li>我们看浏览器直接调用ajax读取文件</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">  $(<span class="string">&quot;button&quot;</span>).<span class="title function_">click</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    $.<span class="title function_">get</span>(<span class="string">&quot;txt/01.txt&quot;</span>,<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">      $.<span class="title function_">get</span>(<span class="string">&quot;txt/02.txt&quot;</span>,<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">        $.<span class="title function_">get</span>(<span class="string">&quot;txt/03.txt&quot;</span>,<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">          <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">        &#125;)</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">888888</span>);</span><br><span class="line">  &#125;)</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>
<ol>
<li>你会发现请求也是异步的，并且也有回调黑洞的问题</li>
<li>我们也可以使用Promise去解决这个问题</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">&quot;button&quot;</span>).<span class="title function_">click</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="title function_">readFile</span>(<span class="string">&quot;txt/01.txt&quot;</span>).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">    <span class="keyword">return</span> <span class="title function_">readFile</span>(<span class="string">&quot;txt/02.txt&quot;</span>)</span><br><span class="line">  &#125;).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">    <span class="keyword">return</span> <span class="title function_">readFile</span>(<span class="string">&quot;txt/03.txt&quot;</span>)</span><br><span class="line">  &#125;).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">  &#125;).<span class="title function_">catch</span>(<span class="function"><span class="params">err</span>=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;读取错误&quot;</span>,err);</span><br><span class="line">  &#125;)</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">88888</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>Promise本质上就是一个“语法糖”</li>
<li>什么是语法糖？语法糖（Syntactic sugar），</li>
<li>也译为糖衣语法，是由英国计算机科学家彼得·约翰·兰达（Peter J. Landin）发明的一个术语，指计算机语言中添加的某种语法</li>
<li>这种语法对语言的功能并没有影响，但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性，从而减少程序代码出错的机会</li>
<li>所以Promise其实就是改变了异步的语法，本质没有改变异步，而是将异步嵌套改为then的连续打点写法</li>
</ol>
<h3 id="Promise-resolve-方法"><a href="#Promise-resolve-方法" class="headerlink" title="Promise.resolve 方法"></a>Promise.resolve 方法</h3><ol>
<li>Promise可以 .then 调用是因为当前的实例是一个 promise对象，promise对象是怎么形成的？我们可以用 promise.resolve方法去创建一个对象</li>
<li>我们看下面的代码</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> pr = <span class="title class_">Promise</span>.<span class="title function_">resolve</span>(<span class="string">&quot;mashibing&quot;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(pr);</span><br></pre></td></tr></table></figure>
<ol>
<li>你会发现上面的代码将”mashibing”封装成了一个带有promise对象的壳子</li>
<li>此时这个pr就可以 .then去使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> pr = <span class="title class_">Promise</span>.<span class="title function_">resolve</span>(<span class="string">&quot;mashibing&quot;</span>);</span><br><span class="line">pr.<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>如果我们resolve方法的参数是一个对象内部有 then方法</li>
<li>Promise.resolve方法会将这个对象转为 Promise对象，然后就立即执行 thenable对象的then方法</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> thenable = &#123;</span><br><span class="line">  <span class="attr">then</span>: <span class="keyword">function</span>(<span class="params">resolve, reject</span>) &#123;</span><br><span class="line">    <span class="title function_">resolve</span>(<span class="number">42</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> p1 = <span class="title class_">Promise</span>.<span class="title function_">resolve</span>(thenable);</span><br><span class="line">p1.<span class="title function_">then</span>(<span class="keyword">function</span>(<span class="params">value</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(value);  <span class="comment">// 42</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<h3 id="Promise-all方法"><a href="#Promise-all方法" class="headerlink" title="Promise.all方法"></a>Promise.all方法</h3><ol>
<li>Promise.all 方法用于将多个Promise实例，包装成一个新的 Promise实例</li>
<li>Promise.all() 又叫<code>等待原则</code>，等待所有的 Promise都执行完后返回</li>
<li>返回一个新的数组，数组是多个 Promise的返回结果。</li>
<li>如果有一个错误，则直接返回错误信息。如果都通过，则返回一个数组</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">readFile</span>(<span class="params">url</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(url,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">      <span class="keyword">if</span>(err)&#123;</span><br><span class="line">        <span class="title function_">reject</span>(err)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="title function_">resolve</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p1 = <span class="title function_">readFile</span>(<span class="string">&quot;txt/01.txt&quot;</span>)</span><br><span class="line"><span class="keyword">var</span> p2 = <span class="title function_">readFile</span>(<span class="string">&quot;txt/02.txt&quot;</span>)</span><br><span class="line"><span class="keyword">var</span> p3 = <span class="title function_">readFile</span>(<span class="string">&quot;txt/03.txt&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="title class_">Promise</span>.<span class="title function_">all</span>([p1,p2,p3]).<span class="title function_">then</span>(<span class="function">(<span class="params">data</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">&#125;).<span class="title function_">catch</span>(<span class="function"><span class="params">err</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">error</span>(err);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>上面代码中，Promise.all方法接受一个数组作为参数，p1、p2、p3都是Promise对象的实例，如果不是，就会先调用到Promise.resolve方法，将参数转为Promise实例，再进一步处理</li>
<li>p的状态由p1、p2、p3决定，分成两种情况。<ol>
<li>只有p1、p2、p3的状态都变成成功状态，p的状态才会变成成功，此时p1、p2、p3的返回值组成一个数组，传递给p的回调函数。</li>
<li>只要p1、p2、p3之中有一个为失败，p的状态就变成失败，此时第一个被reject的实例的返回值，会传递给promise.all的catch回调函数</li>
</ol>
</li>
</ol>
<h3 id="Promise-race方法"><a href="#Promise-race方法" class="headerlink" title="Promise.race方法"></a>Promise.race方法</h3><ol>
<li>Promise.race 方法同样是将多个 Promise实例，包装成一个新的 Promise实例</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">readFile</span>(<span class="params">url</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(url,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">      <span class="keyword">if</span>(err)&#123;</span><br><span class="line">        <span class="title function_">reject</span>(err)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="title function_">resolve</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p1 = <span class="title function_">readFile</span>(<span class="string">&quot;txt/01.txt&quot;</span>)</span><br><span class="line"><span class="keyword">var</span> p2 = <span class="title function_">readFile</span>(<span class="string">&quot;txt/02.txt&quot;</span>)</span><br><span class="line"><span class="keyword">var</span> p3 = <span class="title function_">readFile</span>(<span class="string">&quot;txt/03.txt&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = <span class="title class_">Promise</span>.<span class="title function_">race</span>([p1,p2,p3])</span><br><span class="line">p.<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">&#125;).<span class="title function_">catch</span>(<span class="function"><span class="params">err</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">error</span>(err);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>和promise.all方法不同的是只要p1、p2、p3之中有一个实例率先改变状态，p的状态就跟着改变。那个率先改变的 Promise 实例的返回值，就传递给p的回调函数。</li>
</ol>
<h3 id="Promise-done方法-非ES6提供"><a href="#Promise-done方法-非ES6提供" class="headerlink" title="Promise.done方法-非ES6提供"></a>Promise.done方法-非ES6提供</h3><ol>
<li>Promise对象的回调链，不管以 then方法 或 catch方法 结尾，要是最后一个方法抛出错误，都有可能无法捕捉到（因为Promise内部的错误不会冒泡到全局）。</li>
<li>因此，我们可以提供一个 done方法，总是处于回调链的尾端，保证抛出任何可能出现的错误。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">done</span> = <span class="keyword">function</span>(<span class="params">onFulfilled, onRejected</span>)&#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="title function_">then</span>(onFulfilled, onRejected)</span><br><span class="line">    .<span class="title function_">catch</span>(<span class="keyword">function</span> (<span class="params">reason</span>) &#123;</span><br><span class="line">      <span class="comment">// 抛出一个全局错误</span></span><br><span class="line">      <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123; <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">&quot;信息错误&quot;</span>) &#125;, <span class="number">0</span>);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">readFile</span>(<span class="params">url</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(url,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">      <span class="keyword">if</span>(err)&#123;</span><br><span class="line">        <span class="title function_">reject</span>(err)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="title function_">resolve</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p1 = <span class="title function_">readFile</span>(<span class="string">&quot;txt/011.txt&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = <span class="title class_">Promise</span>.<span class="title function_">race</span>([p1])</span><br><span class="line">p.<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">&#125;).<span class="title function_">done</span>()</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的011.txt是没有的所以抛出全局错误</li>
</ol>
<h3 id="Promise-finally-方法-非ES6提供"><a href="#Promise-finally-方法-非ES6提供" class="headerlink" title="Promise.finally 方法-非ES6提供"></a>Promise.finally 方法-非ES6提供</h3><ol>
<li>finally 方法用于指定不管 Promise对象最后状态如何，都会执行的操作。它与 done方法的最大区别，它接受一个普通的回调函数作为参数，该函数不管怎样都必须执行。</li>
<li>看一下代码实现</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">finally</span> = <span class="keyword">function</span> (<span class="params">callback</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> P = <span class="variable language_">this</span>.<span class="property">constructor</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="title function_">then</span>(</span><br><span class="line">    <span class="function"><span class="params">value</span>  =&gt;</span> P.<span class="title function_">resolve</span>(<span class="title function_">callback</span>()).<span class="title function_">then</span>(<span class="function">() =&gt;</span> value),</span><br><span class="line">    <span class="function"><span class="params">reason</span> =&gt;</span> P.<span class="title function_">resolve</span>(<span class="title function_">callback</span>()).<span class="title function_">then</span>(<span class="function">() =&gt;</span> &#123; <span class="keyword">throw</span> reason &#125;)</span><br><span class="line">  );</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">finally</span> = <span class="keyword">function</span> (<span class="params">callback</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> P = <span class="variable language_">this</span>.<span class="property">constructor</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="title function_">then</span>(</span><br><span class="line">    <span class="function"><span class="params">value</span>  =&gt;</span> P.<span class="title function_">resolve</span>(<span class="title function_">callback</span>()).<span class="title function_">then</span>(<span class="function">() =&gt;</span> value),</span><br><span class="line">    <span class="function"><span class="params">reason</span> =&gt;</span> P.<span class="title function_">resolve</span>(<span class="title function_">callback</span>()).<span class="title function_">then</span>(<span class="function">() =&gt;</span> &#123; <span class="keyword">throw</span> reason &#125;)</span><br><span class="line">  );</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">readFile</span>(<span class="params">url</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(url,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">      <span class="keyword">if</span>(err)&#123;</span><br><span class="line">        <span class="title function_">reject</span>(err)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="title function_">resolve</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p1 = <span class="title function_">readFile</span>(<span class="string">&quot;txt/01.txt&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = <span class="title class_">Promise</span>.<span class="title function_">race</span>([p1])</span><br><span class="line">p.<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">&#125;).<span class="title function_">finally</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;最后的执行&quot;</span>);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="Iterator遍历器"><a href="#Iterator遍历器" class="headerlink" title="Iterator遍历器"></a>Iterator遍历器</h2><h3 id="Iterator（遍历器）的概念"><a href="#Iterator（遍历器）的概念" class="headerlink" title="Iterator（遍历器）的概念"></a>Iterator（遍历器）的概念</h3><ol>
<li>遍历器的作用就是统一的接口机制，来处理所有不同的数据结构,这是一种设计思想</li>
<li>遍历器（Iterator）就是这样一种机制。<code>它是一种接口，为各种不同的数据结构提供统一的访问机制</code>。</li>
<li>任何数据结构只要部署 Iterator接口，就可以完成遍历操作（即依次处理该数据结构的所有成员）。</li>
<li>Iterator 的作用：<ol>
<li>一是为各种数据结构，提供一个统一的、简便的访问接口；</li>
<li>二是使得数据结构的成员能够按某种次序排列</li>
</ol>
</li>
<li>我们应该如何理解这种遍历器的机制？我们可以联想到自己的生活？</li>
<li>比如我们的冰箱、洗衣机、电视虽然功能各自不同，但是有一个 “接口” 是统一的，那就是电源线， 不是两头的就是三头的</li>
<li>iterator 是一种接口机制，我们使用或者设计的时候必须要遵循这种机制</li>
</ol>
<h3 id="Iterator的模拟封装"><a href="#Iterator的模拟封装" class="headerlink" title="Iterator的模拟封装"></a>Iterator的模拟封装</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">makeIterator</span>(<span class="params">array</span>) &#123;</span><br><span class="line">  <span class="comment">// 起始下标</span></span><br><span class="line">  <span class="keyword">var</span> nextIndex = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="comment">// 封装的next方法</span></span><br><span class="line">    <span class="attr">next</span>: <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> nextIndex &lt; array.<span class="property">length</span> ?</span><br><span class="line">        &#123;<span class="attr">value</span>: array[nextIndex++], <span class="attr">done</span>: <span class="literal">false</span>&#125; :</span><br><span class="line">        &#123;<span class="attr">value</span>: <span class="literal">undefined</span>, <span class="attr">done</span>: <span class="literal">true</span>&#125;;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 注册iterator</span></span><br><span class="line"><span class="keyword">var</span> it = <span class="title function_">makeIterator</span>([<span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;2&#x27;</span>,<span class="string">&#x27;3&#x27;</span>]);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的{value:**,done:false}这种格式的返回就是所谓的<code>iterator接口的规则，value表示当前这次遍历出来的值，done表示遍历是否结束。</code> false为未结束，true为已结束</li>
<li>Iterator的遍历过程是这样的。<ol>
<li>创建一个指针对象，指向当前数据结构的起始位置。也就是说，遍历器对象本质上，就是一个指针对象。</li>
<li>第一次调用指针对象的<code>next</code>方法,可以将指针指向数据结构的第一个成员。</li>
<li>第二次调用指针对象的<code>next</code>方法，指针就指向数据结构的第二个成员。</li>
<li>不断调用指针对象的<code>next</code>方法，直到它指向数据结构的结束位置。</li>
</ol>
</li>
<li>每一次调用<code>next</code>方法，都会返回数据结构的当前成员信息，具体的说，就是返回一个包含<code>value</code> 和<code>done</code>两个属性的对象。</li>
<li>其中，<code>value</code>属性是当前成员的值，<code>done</code>属性是一个布尔值，表示遍历是否结束</li>
</ol>
<h3 id="数据结构的默认-Iterator接口"><a href="#数据结构的默认-Iterator接口" class="headerlink" title="数据结构的默认 Iterator接口"></a>数据结构的默认 Iterator接口</h3><ol>
<li>ES6规定，<code>默认的 Iterator接口部署在数据结构的Symbol.iterator属性</code>，或者说，<code>一个数据结构只要具有Symbol.iterator属性，就可以认为是“可遍历的”（iterable）</code></li>
<li>比如我们的数组就是拥有遍历器能力的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr);</span><br></pre></td></tr></table></figure>
<ol>
<li>如何使用遍历器？</li>
<li>比如数组</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>];</span><br><span class="line"><span class="comment">// 注册iterator</span></span><br><span class="line"><span class="keyword">var</span> it = arr[<span class="title class_">Symbol</span>.<span class="property">iterator</span>]();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br></pre></td></tr></table></figure>
<ol>
<li>在ES6中，有三类数据结构原生具备 Iterator接口：数组、某些类似数组的 对象、String、Set 和 Map结构</li>
</ol>
<h3 id="for-of循环"><a href="#for-of循环" class="headerlink" title="for..of循环"></a>for..of循环</h3><ol>
<li>一个数据结构只要部署了<code>Symbol.iterator</code>属性，就被视为具有 <code>iterator接口</code>，就可以用 <code>for...of循环遍历</code>它的成员</li>
<li>比如数组</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">22</span>,<span class="number">33</span>,<span class="number">44</span>,<span class="number">55</span>,<span class="number">66</span>];</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> item <span class="keyword">of</span> arr)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>再比如arguments对象</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">printArgs</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> x <span class="keyword">of</span> <span class="variable language_">arguments</span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(x);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">printArgs</span>(<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>);<span class="comment">// a,b</span></span><br></pre></td></tr></table></figure>
<ol>
<li>除了<code>for...of循环</code>以外，<code>扩展运算符（...）</code>、<code>解构赋值</code>和 <code>Array.from方法内部调用</code>的，都是遍历器接口</li>
</ol>
<h2 id="Generator-函数"><a href="#Generator-函数" class="headerlink" title="Generator 函数"></a>Generator 函数</h2><h3 id="Generator概念"><a href="#Generator概念" class="headerlink" title="Generator概念"></a>Generator概念</h3><ol>
<li>Generator函数也是解决异步的函数，也可以理解为一个状态机</li>
<li>执行Generator函数会返回一个遍历器对象，也就是说，Generator函数除了状态机，还是一个遍历器对象生成函数。返回的遍历器对象，可以依次遍历Generator函数内部的每一个状态。</li>
<li>熟悉语法：</li>
<li>形式上，Generator函数是一个普通函数，但是有两个特征。一是，function关键字与函数名之间有一个星号；二是，函数体内部使用yield语句，定义不同的内部状态（yield语句在英语里的意思就是“产出”）。</li>
</ol>
<h3 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span>* <span class="title function_">helloWorldGenerator</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;a&quot;</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;b&quot;</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;c&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> it = <span class="title function_">helloWorldGenerator</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br></pre></td></tr></table></figure>
<ol>
<li>函数内部的 yield来划分分段执行的返回，和return一样都有返回值的功能，但是不同的是return只能执行一次，但是yield可以多次执行。return会阻止后面代码的执行，但是yield不会</li>
<li>Generator函数的调用方法与普通函数一样，也是在函数名后面加上一对圆括号。不同的是，调用Generator函数后，该函数并不执行，返回的也不是函数运行结果，而是一个指向内部状态的指针对象，也就是上一章介绍的遍历器对象（Iterator ）。</li>
<li>Generator函数是分段执行的，yield语句是暂停执行的标记，而next方法可以恢复执行。</li>
</ol>
<h3 id="Generator的return问题"><a href="#Generator的return问题" class="headerlink" title="Generator的return问题"></a>Generator的return问题</h3><ol>
<li>如果Generator函数内部的最后一个值是return，此时不会被for..遍历出来</li>
<li>我们先看yield返回的情况</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span>* <span class="title function_">helloWorldGenerator</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;a&quot;</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;b&quot;</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;c&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> it = <span class="title function_">helloWorldGenerator</span>();</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> item <span class="keyword">of</span> it) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>此时会正常返回a，b，c</li>
<li>但是如果将最后一次的yield变为return</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span>* <span class="title function_">helloWorldGenerator</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;a&quot;</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;b&quot;</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&quot;c&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> it = <span class="title function_">helloWorldGenerator</span>();</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> item <span class="keyword">of</span> it) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>.next方法是可以传入参数的，但是这个参数很诡异，第一次实现的传参不能输出</li>
<li>yield句本身没有返回值，或者说总是返回undefined。next方法可以带一个参数，该参数就会被当作上一个yield语句的返回值</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span>* <span class="title function_">helloWorldGenerator</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">const</span> a = <span class="keyword">yield</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(a);</span><br><span class="line">  <span class="keyword">const</span> b = <span class="keyword">yield</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(b);</span><br><span class="line">  <span class="keyword">const</span> c = <span class="keyword">yield</span></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(c);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> it = <span class="title function_">helloWorldGenerator</span>();</span><br><span class="line"></span><br><span class="line">it.<span class="title function_">next</span>(<span class="number">10</span>)</span><br><span class="line">it.<span class="title function_">next</span>(<span class="number">20</span>)</span><br><span class="line">it.<span class="title function_">next</span>(<span class="number">30</span>)</span><br><span class="line">it.<span class="title function_">next</span>(<span class="number">40</span>)</span><br></pre></td></tr></table></figure>
<h3 id="yield语句"><a href="#yield语句" class="headerlink" title="yield语句"></a>yield语句</h3><ol>
<li>由于 Generator 函数返回的遍历器对象，只有调用next方法才会遍历下一个内部状态，所以其实提供了一种可以暂停执行的函数。yield语句就是暂停标志。</li>
<li>遍历器对象的 next方法的运行逻辑如下。<ol>
<li>遇到 yield 语句，就暂停执行后面的操作，并将紧跟在 yield后面的那个表达式的值，作为返回的对象的value属性值。</li>
<li>下一次调用 next方法时，再继续往下执行，直到遇到下一个 yield语句。</li>
<li>如果没有再遇到新的 yield语句，就一直运行到函数结束，直到 return语句为止，并将 return语句后面的表达式的值，作为返回的对象的 value属性值。</li>
<li>如果该函数没有 return语句，则返回的对象的 value属性值为 undefined。</li>
</ol>
</li>
<li>普通函数中不能使用yield</li>
</ol>
<h3 id="对象生成-iterator遍历器"><a href="#对象生成-iterator遍历器" class="headerlink" title="对象生成 iterator遍历器"></a>对象生成 iterator遍历器</h3><ol>
<li>我们前面知道原生数据结构中对象是没有 symbol.iterator属性，所以我们可以利用 Generator函数去生成</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myIterable = &#123;&#125;;</span><br><span class="line">myIterable[<span class="title class_">Symbol</span>.<span class="property">iterator</span>] = <span class="keyword">function</span>* () &#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">1</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">2</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">3</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> it = myIterable[<span class="title class_">Symbol</span>.<span class="property">iterator</span>]()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br></pre></td></tr></table></figure>
<h3 id="Generator-的-return方法"><a href="#Generator-的-return方法" class="headerlink" title="Generator 的 return方法"></a>Generator 的 return方法</h3><ol>
<li>Generator 函数返回的遍历器对象，还有一个 return方法，可以返回给定的值，并且终结遍历 Generator函数。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span>* <span class="title function_">gen</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">1</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">2</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">3</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> g = <span class="title function_">gen</span>();</span><br><span class="line"></span><br><span class="line">g.<span class="title function_">next</span>()        <span class="comment">// &#123; value: 1, done: false &#125;</span></span><br><span class="line">g.<span class="keyword">return</span>(<span class="string">&#x27;foo&#x27;</span>) <span class="comment">// &#123; value: &quot;foo&quot;, done: true &#125;</span></span><br><span class="line">g.<span class="title function_">next</span>()        <span class="comment">// &#123; value: undefined, done: true &#125;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>上面代码中，遍历器对象 g调用 return方法后，返回值的 value属性就是 return方法的参数foo。并且，Generator函数的遍历就终止了，返回值的 done属性为true，以后再 调用next方法，done属性总是返回 true。</li>
<li>Generator内部 return也会造成状态终止</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myIterable = &#123;&#125;;</span><br><span class="line">myIterable[<span class="title class_">Symbol</span>.<span class="property">iterator</span>] = <span class="keyword">function</span>* () &#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">1</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">2</span>;</span><br><span class="line">  <span class="keyword">return</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">3</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> it = myIterable[<span class="title class_">Symbol</span>.<span class="property">iterator</span>]()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(it.<span class="title function_">next</span>());</span><br></pre></td></tr></table></figure>
<h3 id="yield"><a href="#yield" class="headerlink" title="yield*"></a>yield*</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span>* <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&#x27;b&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span>* <span class="title function_">bar</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&#x27;x&#x27;</span>;</span><br><span class="line">  <span class="title function_">foo</span>();</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&#x27;y&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> v <span class="keyword">of</span> <span class="title function_">bar</span>())&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(v);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>这个就需要用到 yield*语句，用来在一个 Generator函数里面执行另一个 Generator函数。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span>* <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&#x27;b&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span>* <span class="title function_">bar</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&#x27;x&#x27;</span>;</span><br><span class="line">  <span class="keyword">yield</span>* <span class="title function_">foo</span>();</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&#x27;y&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> v <span class="keyword">of</span> <span class="title function_">bar</span>())&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(v);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="Generator的应用场景"><a href="#Generator的应用场景" class="headerlink" title="Generator的应用场景"></a>Generator的应用场景</h3><ol>
<li>我们还是读取文件</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> readFile = <span class="keyword">function</span>(<span class="params">url</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(url,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(err)&#123;</span><br><span class="line">          <span class="title function_">reject</span>(err)</span><br><span class="line">          <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="title function_">resolve</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  )</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Generator定义</span></span><br><span class="line"><span class="keyword">function</span> * <span class="title function_">asyncReadFile</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/01.txt&quot;</span>);</span><br><span class="line">  <span class="keyword">yield</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/02.txt&quot;</span>);</span><br><span class="line">  <span class="keyword">yield</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/03.txt&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> gen = <span class="title function_">asyncReadFile</span>();</span><br><span class="line">gen.<span class="title function_">next</span>().<span class="property">value</span>.<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">  <span class="keyword">return</span> gen.<span class="title function_">next</span>().<span class="property">value</span>;</span><br><span class="line">&#125;).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">  <span class="keyword">return</span> gen.<span class="title function_">next</span>().<span class="property">value</span>;</span><br><span class="line">&#125;).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="async和await"><a href="#async和await" class="headerlink" title="async和await"></a>async和await</h2><ol>
<li>async函数是什么？一句话，<code>async函数就是 Generator函数的语法糖</code>。</li>
<li>ES7中提出的 async函数，它能解决<code>Promise连续then的一个火车黑洞问题</code></li>
</ol>
<h3 id="基本使用-1"><a href="#基本使用-1" class="headerlink" title="基本使用"></a>基本使用</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> readFile = <span class="keyword">function</span>(<span class="params">url</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve,reject</span>)=&gt;</span>&#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(url,<span class="function">(<span class="params">err,content</span>)=&gt;</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(err)&#123;</span><br><span class="line">          <span class="title function_">reject</span>(err)</span><br><span class="line">          <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="title function_">resolve</span>(content.<span class="title function_">toString</span>())</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  )</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">files</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">const</span> data1 = <span class="keyword">await</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/01.txt&quot;</span>);</span><br><span class="line">  <span class="keyword">const</span> data2 = <span class="keyword">await</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/02.txt&quot;</span>);</span><br><span class="line">  <span class="keyword">const</span> data3 = <span class="keyword">await</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/03.txt&quot;</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data1);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data2);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data3);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">files</span>()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">888888</span>);</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<ol>
<li>你会发现，结果会输出并且是异步执行的</li>
<li>你会发现上面 files函数中 await语句后面的 readFile没有使用 .then，也能返回结果，此时和我们加 then的效果是一样的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">files</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">const</span> data1 = <span class="keyword">await</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/01.txt&quot;</span>).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>data);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data1); <span class="comment">// AAAAAAAAAA</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>任何一个函数都能加 async这个关键词，表示这个函数内部要书写异步代码</li>
<li>async表示定义当前的函数为一个异步函数，<code>await只能用在 async定义的函数内有效，表示等待异步读取的结果，如果在普通函数中会报错</code></li>
<li>此时我们再思考一个问题，函数内部是如何运行的？</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">files</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">const</span> data1 = <span class="keyword">await</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/01.txt&quot;</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">6666</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data1);</span><br><span class="line">  <span class="keyword">const</span> data2 = <span class="keyword">await</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/02.txt&quot;</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">777</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data2);</span><br><span class="line">  <span class="keyword">const</span> data3 = <span class="keyword">await</span> <span class="title function_">readFile</span>(<span class="string">&quot;./txt/03.txt&quot;</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">888</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data3);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">files</span>()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">888888</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>此时你会发现先输出888888，表示当前整个函数是异步的，然后函数体内部是按照同步代码执行的，也就是 <code>await将异步语句变为了同步语句在执行</code></li>
</ol>
<h3 id="async函数"><a href="#async函数" class="headerlink" title="async函数"></a>async函数</h3><ol>
<li><code>async函数返回一个Promise对象。</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">f</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&#x27;hello world&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">f</span>());</span><br></pre></td></tr></table></figure>
<ol>
<li>此时可以通过then来调用获取值</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">f</span>().<span class="title function_">then</span>(<span class="function"><span class="params">v</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(v)) <span class="comment">// hello world</span></span><br></pre></td></tr></table></figure>
<ol>
<li>函数内部抛出错误，会导致返回的 <code>Promise对象变为 reject状态。抛出的错误对象会 被catch方法回调函数接收到</code>。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">f</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">&#x27;出错了&#x27;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">f</span>().<span class="title function_">then</span>(</span><br><span class="line">  <span class="function"><span class="params">v</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(v),</span><br><span class="line">  <span class="function"><span class="params">e</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(e)</span><br><span class="line">) <span class="comment">// Error: 出错了</span></span><br></pre></td></tr></table></figure>
<h3 id="await命令"><a href="#await命令" class="headerlink" title="await命令"></a>await命令</h3><ol>
<li><code>await命令后面是一个 Promise对象。如果不是，会被转成一个立即resolve的Promise对象。</code></li>
<li>也就是说，如果不是 promise对象，此时函数内部返回的时候会自动包一个promise的壳子</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">f</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">await</span> <span class="number">123</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">f</span>().<span class="title function_">then</span>(<span class="function"><span class="params">v</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(v)) <span class="comment">//123</span></span><br></pre></td></tr></table></figure>
<ol>
<li><code>await命令后面的 Promise对象如果变为 reject状态，则 reject的参数会被 catch方法的回调函数接收到。</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">f</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">await</span> <span class="title class_">Promise</span>.<span class="title function_">reject</span>(<span class="string">&#x27;出错了&#x27;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">f</span>()</span><br><span class="line">.<span class="title function_">then</span>(<span class="function"><span class="params">v</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(v))</span><br><span class="line">.<span class="title function_">catch</span>(<span class="function"><span class="params">e</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(e)) <span class="comment">// 出错了</span></span><br></pre></td></tr></table></figure>
<h3 id="async函数的错误机制问题"><a href="#async函数的错误机制问题" class="headerlink" title="async函数的错误机制问题"></a>async函数的错误机制问题</h3><ol>
<li>我们可以通过 try-catch 来进行错误机制的处理</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">f</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">await</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="keyword">function</span> (<span class="params">resolve, reject</span>) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">&#x27;文件读取错误&#x27;</span>);</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125; <span class="keyword">catch</span>(e) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;错误信息&quot;</span>,e);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">await</span>(<span class="string">&#x27;hello world&#x27;</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">f</span>().<span class="title function_">then</span>()</span><br></pre></td></tr></table></figure>
<h3 id="async函数的多种使用形式"><a href="#async函数的多种使用形式" class="headerlink" title="async函数的多种使用形式"></a>async函数的多种使用形式</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 函数声明</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数表达式</span></span><br><span class="line"><span class="keyword">const</span> foo = <span class="keyword">async</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 对象的方法</span></span><br><span class="line"><span class="keyword">let</span> obj = &#123; <span class="keyword">async</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;&#125; &#125;;</span><br><span class="line">obj.<span class="title function_">foo</span>().<span class="title function_">then</span>(...)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Class 的方法</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Storage</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">cachePromise</span> = caches.<span class="title function_">open</span>(<span class="string">&#x27;avatars&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">async</span> <span class="title function_">getAvatar</span>(<span class="params">name</span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> cache = <span class="keyword">await</span> <span class="variable language_">this</span>.<span class="property">cachePromise</span>;</span><br><span class="line">    <span class="keyword">return</span> cache.<span class="title function_">match</span>(<span class="string">`/avatars/<span class="subst">$&#123;name&#125;</span>.jpg`</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> storage = <span class="keyword">new</span> <span class="title class_">Storage</span>();</span><br><span class="line">storage.<span class="title function_">getAvatar</span>(<span class="string">&#x27;jake&#x27;</span>).<span class="title function_">then</span>(…);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 箭头函数</span></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">foo</span> = <span class="keyword">async</span> (<span class="params"></span>) =&gt; &#123;&#125;;</span><br></pre></td></tr></table></figure>
<h3 id="for-await-of遍历异步"><a href="#for-await-of遍历异步" class="headerlink" title="for await..of遍历异步"></a>for await..of遍历异步</h3><ol>
<li><code>for...of 循环</code>用于<code>遍历同步的</code> Iterator接口。新引入的 <code>for await...of循环</code>，则是用于<code>遍历异步的</code>Iterator接口。</li>
<li>下面的代码是伪代码</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">f</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">for</span> <span class="keyword">await</span> (<span class="keyword">const</span> x <span class="keyword">of</span> <span class="title function_">createAsyncIterable</span>([<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>])) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(x); <span class="comment">// a,b</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>createAsyncIterable([‘a’, ‘b’])是一个假设的异步的函数返回，[‘a’, ‘b’]是入参</li>
<li>也可以当做同步遍历器</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">(<span class="keyword">async</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">for</span> <span class="keyword">await</span> (<span class="keyword">const</span> x <span class="keyword">of</span> [<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>]) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(x);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)(); <span class="comment">// a,b</span></span><br></pre></td></tr></table></figure>
<h2 id="fetch请求"><a href="#fetch请求" class="headerlink" title="fetch请求"></a>fetch请求</h2><h3 id="基本使用-2"><a href="#基本使用-2" class="headerlink" title="基本使用"></a>基本使用</h3><ol>
<li>我们之前学习的 <code>async</code>和<code>await</code>函数返回的都是一个<code>promise</code>对象，比如我们的异步请求，</li>
<li>如果没有封装 promise对象，自己还需要再次进行封装之后才能在<code>async</code>内部进行使用，此时可以用<code>fetch</code>来解决这个问题，<code>fetch返回的也是一个 promise对象</code></li>
<li>fetch一般都是用在浏览器端的，少用在 node端</li>
<li>参考资料：<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch">https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch</a></li>
<li>看一下基本使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">  <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">readFile</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">const</span> data1 = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&quot;txt/01.txt&quot;</span>).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>data.<span class="title function_">text</span>());</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(data1);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">readFile</span>()</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们看上面代码，fetch返回的是一个promise对象，就可以通过.then来进行获取操作，内部的data.text()指的获取text文本</li>
<li>一共有几种数据格式？<ol>
<li>arrayBuffer()</li>
<li>blob()</li>
<li>json()</li>
<li>text()</li>
<li>formData()</li>
</ol>
</li>
<li>我们常用就是<code>json() 和 text()</code></li>
<li>我们看一下使用json获取</li>
<li>此时我们创建一个04.json</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="string">&quot;a&quot;</span>:<span class="number">100</span>,</span><br><span class="line">  <span class="string">&quot;b&quot;</span>:<span class="number">200</span>,</span><br><span class="line">  <span class="string">&quot;c&quot;</span>:<span class="number">300</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>比如我们要获取a</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">  <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">readFile</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;a&#125; = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&quot;txt/04.json&quot;</span>).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>data.<span class="title function_">json</span>());</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(a);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">readFile</span>()</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>
<ol>
<li>总结一下：<code>fetch 返回的是 promise 对象</code>，一般是在<code>浏览器端</code>使用，<code>发送请求</code>，支持多种请求，有不同的方法获取 <code>body</code> 返回值，我们大多数用的是 <code>text 和 json方法</code></li>
</ol>
<h3 id="fetch的优缺点"><a href="#fetch的优缺点" class="headerlink" title="fetch的优缺点"></a>fetch的优缺点</h3><ol>
<li>为什么要用 fetch，原生的 XMLHttpRequest 是一个很笨重的实现，没有整体的封装性，配置和调用方式很混乱</li>
<li>我们看一下下面的代码</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xhr = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">xhr.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>,<span class="string">&quot;http://www.baidu.com&quot;</span>)</span><br><span class="line"></span><br><span class="line">xhr.<span class="property">onload</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(xhr.<span class="property">response</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">xhr.<span class="title function_">send</span>()</span><br></pre></td></tr></table></figure>
<ol>
<li><code>fetch</code>是 JavaScript的<code>语言封装</code>，<code>是对XMLHttpRequest封装</code>，不是第三方库的封装，不同于jquery的 ajax</li>
<li>fetch也有自己的确定，兼容性不好，目前大多数使用在浏览器端，如果想要在 node中使用，只用原生的 api是不支持，得引用第三方插件 node-fetch</li>
</ol>
<h3 id="fetch-和-jquery-的区别"><a href="#fetch-和-jquery-的区别" class="headerlink" title="fetch 和 jquery 的区别"></a>fetch 和 jquery 的区别</h3><ol>
<li>当接收到一个代表错误的 <code>HTTP 状态码</code>时，从 <code>fetch()</code> 返回的 <code>Promise</code> 不会被标记为 <code>reject</code>， 即使响应的<code>HTTP 状态码是 404 或 500</code>。相反，它会将 <code>Promise</code> 状态标记为 <code>resolve</code> （但是会将 <code>resolve</code> 的返回值的 ok 属性设置为 <code>false</code> ），仅当网络故障时或请求被阻止时，才会标记为 <code>reject。</code></li>
<li><code>fetch() 可以接受跨域 cookies</code>；你也可以使用 fetch() 建立起跨域会话。</li>
<li><code>fetch 不会发送 cookies</code>。除非你使用了 <code>credentials</code> 的初始化选项。（自 2017 年 8 月 25 日以后，默认的 credentials 政策变更为 same-origin。Firefox 也在 61.0b13 版本中进行了修改）</li>
</ol>
<h3 id="fetch的请求"><a href="#fetch的请求" class="headerlink" title="fetch的请求"></a>fetch的请求</h3><ol>
<li><code>fetch</code>默认的请求是<code>get请求</code>，如果发送<code>post请求</code>，需要配置<code>body</code>信息</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">  $(<span class="string">&quot;button&quot;</span>).<span class="title function_">click</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title function_">fetch</span>(<span class="string">&quot;fetch_methods&quot;</span>,&#123;</span><br><span class="line">      <span class="comment">// 请求方式</span></span><br><span class="line">      <span class="attr">method</span>: <span class="string">&quot;post&quot;</span>,</span><br><span class="line">      <span class="comment">// 请求头信息</span></span><br><span class="line">      <span class="attr">headers</span>:&#123;</span><br><span class="line">        <span class="string">&quot;content-type&quot;</span>:<span class="string">&#x27;application/json&#x27;</span></span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="comment">// 携带参数</span></span><br><span class="line">      <span class="attr">body</span>: <span class="string">&quot;name=xiaoming&amp;age=12&quot;</span></span><br><span class="line">    &#125;).<span class="title function_">then</span>(<span class="function"><span class="params">data</span>=&gt;</span>&#123;data&#125;).<span class="title function_">catch</span>(<span class="function"><span class="params">err</span>=&gt;</span>&#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;错误信息&quot;</span>,err);</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>
<ol>
<li>如果是post请求，此时需要第二个参数为对象，<code>method</code>表示请求方式，<code>headers</code>是请求头部信息，<code>body</code>是上行请求携带的参数</li>
</ol>
<h2 id="Set-和-WeakSet"><a href="#Set-和-WeakSet" class="headerlink" title="Set 和 WeakSet"></a>Set 和 WeakSet</h2><ol>
<li>我们在之前学习的数据集合，主要有<code>数组和对象</code>，接下来补充几个新的数据结构 Set、WeakSet、Map、WeakMap</li>
</ol>
<h3 id="Set的基本使用"><a href="#Set的基本使用" class="headerlink" title="Set的基本使用"></a>Set的基本使用</h3><ol>
<li><code>set</code>类似于<code>数组</code>的，主要的区别：是有自己的方法并且内部集合不能有重复</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 插入数据</span></span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;b&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;c&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeSet);</span><br></pre></td></tr></table></figure>
<ol>
<li>我们发现返回的结果是一个 <code>set集合</code>，<code>和数组对象都不一样，是一个新的数据集合</code></li>
<li>设置初始值的方法有两种，第一种：是通过<code>add()方法</code>进行设置的，第二种：<code>就是初始化的时候内部设置数组</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeSet);</span><br></pre></td></tr></table></figure>
<ol>
<li>注意：如果要用<code>初始化赋值的状态</code>，赋值必须是<code>数组</code>，不可以是<code>对象</code></li>
<li>set内部的赋值不能有重复</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 插入数据</span></span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;b&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;b&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;b&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;c&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;c&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;c&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>);</span><br><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeSet);</span><br></pre></td></tr></table></figure>
<ol>
<li>也可以连续打点使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> <span class="title class_">Set</span>().<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>).<span class="title function_">add</span>(<span class="string">&quot;b&quot;</span>).<span class="title function_">add</span>(<span class="string">&quot;c&quot;</span>)</span><br></pre></td></tr></table></figure>
<h3 id="Set的方法"><a href="#Set的方法" class="headerlink" title="Set的方法"></a>Set的方法</h3><ol>
<li>插入值使用的是 <code>add方法</code><ol>
<li>向 Set 加入值的时候，不会发生类型转换，所以 <code>5和&quot;5&quot;</code> 是两个不同的值。</li>
</ol>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">typeSet.<span class="title function_">add</span>(<span class="string">&quot;a&quot;</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>删除值使用的是 <code>delete方法</code><ol>
<li>内部想删除哪个数据就填哪个数据</li>
</ol>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line">typeSet.<span class="title function_">delete</span>(<span class="number">3</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeSet);</span><br></pre></td></tr></table></figure>
<ol>
<li>检测内部是否有该值 <code>has()</code>，返回一个布尔值<ol>
<li>上面结果返回的是true，因为typeSet集合中有5这个值</li>
</ol>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeSet.<span class="title function_">has</span>(<span class="number">5</span>)); <span class="comment">//true</span></span><br></pre></td></tr></table></figure>
<ol>
<li>判断集合的长度，<code>size方法</code><ol>
<li>判断长度不是<code>length</code>，而是<code>size</code></li>
</ol>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeSet.<span class="property">size</span>); <span class="comment">//5</span></span><br></pre></td></tr></table></figure>
<ol>
<li>清空集合内部所有的数据，<code>clear()</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line">typeSet.<span class="title function_">clear</span>()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeSet);</span><br></pre></td></tr></table></figure>
<h3 id="关于set的循环"><a href="#关于set的循环" class="headerlink" title="关于set的循环"></a>关于set的循环</h3><ol>
<li><code>map</code>和<code>set</code>我们之前了解了可以使用<code>for..of</code>进行遍历，是因为<code>map</code>和<code>set</code>都是<code>iterator接口机制</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> item <span class="keyword">of</span> typeSet) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们可以使用<code>keys</code>和<code>values</code>进行遍历来看一下<code>set</code>集合<code>key</code>和<code>value</code>分别是什么</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> item <span class="keyword">of</span> typeSet.<span class="title function_">keys</span>()) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item); <span class="comment">// 1,2,3,4,5</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> item <span class="keyword">of</span> typeSet.<span class="title function_">values</span>()) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item); <span class="comment">// 1,2,3,4,5</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>通过上面你会发现 <code>set</code>结合的 <code>key</code> 和 <code>value</code>是相同的</li>
<li>set 也可以用 <code>forEach</code> 去遍历</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">typeSet.<span class="title function_">forEach</span>(<span class="function">(<span class="params">item,index</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item,index);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>set也可以使用<code>entries</code>方法去遍历</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line">  <span class="keyword">for</span>(<span class="keyword">let</span> item <span class="keyword">of</span> typeSet.<span class="title function_">entries</span>()) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(item);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="set-转换为数组"><a href="#set-转换为数组" class="headerlink" title="set 转换为数组"></a>set 转换为数组</h3><ol>
<li>由于 <code>set不能使用数组的方法</code>，虽然 <code>forEach</code>可以用，但是仅仅是 <code>forEach</code>方法，其他是不可以的，比如<code>map、filter</code></li>
<li>下面的方法是错误的，因为<code>map是数组的方法</code>，<code>set</code>不能用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line">typeSet = typeSet.<span class="title function_">map</span>(<span class="function">(<span class="params">item</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="keyword">return</span> item * <span class="number">2</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>所以如果我们想操作set中的数据，需要将set转换为数组</li>
<li>如何转换？<code>…扩展运算符</code>是有<code>iterator接口机制</code>，所以 <code>set</code>就可以使用<code>…运算符</code></li>
<li>来看 set转换为数组</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>([...typeSet]);</span><br></pre></td></tr></table></figure>
<ol>
<li>我们可以将set的内部值统一乘以2</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeSet = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">new</span> <span class="title class_">Set</span>([...typeSet].<span class="title function_">map</span>(<span class="function"><span class="params">item</span>=&gt;</span>item*<span class="number">2</span>)));</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的代码是先将set通过…运算符转换为普通数组</li>
<li>我们也可以利用<code>set</code>和<code>数组的各自特点</code>做<code>去重</code>，比如数组的去重</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr = [<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">3</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">4</span>]</span><br><span class="line"><span class="keyword">let</span> arr2 = [...<span class="keyword">new</span> <span class="title class_">Set</span>(arr)];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr2);</span><br></pre></td></tr></table></figure>
<h3 id="WeakSet-的使用"><a href="#WeakSet-的使用" class="headerlink" title="WeakSet 的使用"></a>WeakSet 的使用</h3><ol>
<li><p><code>Set</code> 和 <code>WeakSet</code> 的区别是 <code>set内部建议存放数组</code>，<code>WeakSet内部建议存放引用类型（数组和对象）</code></p>
</li>
<li><p>虽然<code>WeakSet</code>内部建议存放对象，但是 <code>WeakSet</code>初始化的时候也不能进行初始化赋值，必须使用<code>add</code>赋值</p>
</li>
</ol>
<p>先来看 set内部存放对象</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> setObj = <span class="keyword">new</span> <span class="title class_">Set</span>()</span><br><span class="line">setObj.<span class="title function_">add</span>(&#123;</span><br><span class="line">  <span class="string">&quot;a&quot;</span>:<span class="number">1</span>,</span><br><span class="line">  <span class="string">&quot;b&quot;</span>:<span class="number">2</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(setObj);</span><br></pre></td></tr></table></figure>
<ol>
<li>再来看WeakSet</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> setObj = <span class="keyword">new</span> <span class="title class_">WeakSet</span>()</span><br><span class="line">setObj.<span class="title function_">add</span>(&#123;</span><br><span class="line">  <span class="string">&quot;a&quot;</span>:<span class="number">1</span>,</span><br><span class="line">  <span class="string">&quot;b&quot;</span>:<span class="number">2</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(setObj);</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的 <code>WeakSet</code>是使用 <code>add</code>方法进行的赋值，如果使用初始化赋值会报错</li>
<li>下面的代码会报错，不能初始化赋值对象</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> setObj = <span class="keyword">new</span> <span class="title class_">WeakSet</span>(&#123;</span><br><span class="line">  <span class="string">&quot;a&quot;</span>:<span class="number">1</span>,</span><br><span class="line">  <span class="string">&quot;b&quot;</span>:<span class="number">2</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(setObj);</span><br></pre></td></tr></table></figure>
<h3 id="WeakSet的方法"><a href="#WeakSet的方法" class="headerlink" title="WeakSet的方法"></a>WeakSet的方法</h3><ol>
<li><code>WeakSet</code>也是用<code>add</code>进行赋值的，但是内部接收的是引用类型值，不能是基本类型值</li>
<li>下面的代码会报错</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> setObj = <span class="keyword">new</span> <span class="title class_">WeakSet</span>()</span><br><span class="line">setObj.<span class="title function_">add</span>(<span class="string">&#x27;a&#x27;</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>使用引用类型值</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> setObj = <span class="keyword">new</span> <span class="title class_">WeakSet</span>()</span><br><span class="line">setObj.<span class="title function_">add</span>(&#123;</span><br><span class="line">  <span class="attr">a</span>:<span class="number">100</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li><code>WeakSet</code> 没有 <code>size</code> 属性，也没有 <code>clear</code>方法，也不能使用 <code>for..of</code> 进行遍历</li>
</ol>
<h2 id="Map-和-WeakMap"><a href="#Map-和-WeakMap" class="headerlink" title="Map 和 WeakMap"></a>Map 和 WeakMap</h2><ol>
<li><code>Set</code>类似于数组，<code>Map</code>类似于对象。</li>
<li>为什么要有<code>Map</code>，我们学习对象的时候，<code>key（键）</code>只能是<code>基本类型值``（字面量类型，多数是字符串）</code>，<code>Map</code>的<code>key</code>可以是任意类型</li>
</ol>
<h3 id="基本使用-3"><a href="#基本使用-3" class="headerlink" title="基本使用"></a>基本使用</h3><ol>
<li>看一下基本使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> typeMap = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line"></span><br><span class="line">typeMap.<span class="title function_">set</span>(<span class="string">&quot;a&quot;</span>,<span class="number">100</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeMap);</span><br></pre></td></tr></table></figure>
<ol>
<li>通过上图你会发现，<code>Map</code>有<code>key</code>，并且可以单独设置<code>key</code>，<code>Set</code> 的<code>key</code>和<code>value</code>是相同，上面代码中的第一个参数a是定义对象的<code>key</code>，第二个参数100是定义对象<code>value</code></li>
<li><code>Map方法</code>初始化赋值可以<code>连续打点</code>（类似于jquery的方法）</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> <span class="title class_">Map</span>().<span class="title function_">set</span>(<span class="literal">true</span>, <span class="number">7</span>).<span class="title function_">set</span>(&#123;<span class="attr">foo</span>: <span class="number">3</span>&#125;, [<span class="string">&#x27;abc&#x27;</span>]);</span><br></pre></td></tr></table></figure>
<ol>
<li><code>Map</code>的初始化赋值可以是<code>数组</code>不可以是<code>对象</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>([</span><br><span class="line">  [<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;张三&#x27;</span>],</span><br><span class="line">  [<span class="string">&#x27;title&#x27;</span>, <span class="string">&#x27;Author&#x27;</span>]</span><br><span class="line">]);</span><br><span class="line"></span><br><span class="line">map.<span class="property">size</span> <span class="comment">// 2</span></span><br><span class="line">map.<span class="title function_">has</span>(<span class="string">&#x27;name&#x27;</span>) <span class="comment">// true</span></span><br><span class="line">map.<span class="title function_">get</span>(<span class="string">&#x27;name&#x27;</span>) <span class="comment">// &quot;张三&quot;</span></span><br><span class="line">map.<span class="title function_">has</span>(<span class="string">&#x27;title&#x27;</span>) <span class="comment">// true</span></span><br><span class="line">map.<span class="title function_">get</span>(<span class="string">&#x27;title&#x27;</span>) <span class="comment">// &quot;Author&quot;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>需要注意的是 Map方法初始化对象的赋值只能通过 set方法来设置，不能初始化结构赋值</li>
<li>下面的初始化赋值的写法是错误的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> typeMap = <span class="keyword">new</span> <span class="title class_">Map</span>(&#123;<span class="attr">a</span>:<span class="number">100</span>&#125;);</span><br></pre></td></tr></table></figure>
<h3 id="Map的key可以是任意类型"><a href="#Map的key可以是任意类型" class="headerlink" title="Map的key可以是任意类型"></a>Map的key可以是任意类型</h3><ol>
<li>我们可以设置<code>Map</code>的<code>key</code>为<code>任意类型</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> typeMap = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> objKey = &#123;</span><br><span class="line">  <span class="string">&quot;a&quot;</span>:<span class="number">100</span>,</span><br><span class="line">  <span class="string">&quot;b&quot;</span>:<span class="number">200</span></span><br><span class="line">&#125;</span><br><span class="line">typeMap.<span class="title function_">set</span>(objKey,<span class="string">&quot;200&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeMap);</span><br></pre></td></tr></table></figure>
<ol>
<li>如果对同一个键多次赋值，后面的值将覆盖前面的值。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line"></span><br><span class="line">map</span><br><span class="line">.<span class="title function_">set</span>(<span class="number">1</span>, <span class="string">&#x27;aaa&#x27;</span>)</span><br><span class="line">.<span class="title function_">set</span>(<span class="number">1</span>, <span class="string">&#x27;bbb&#x27;</span>);</span><br><span class="line"></span><br><span class="line">map.<span class="title function_">get</span>(<span class="number">1</span>) <span class="comment">// &quot;bbb&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="Map的方法和属性"><a href="#Map的方法和属性" class="headerlink" title="Map的方法和属性"></a>Map的方法和属性</h3><ol>
<li><code>Map集合</code>也有自己的<code>size</code>属性</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">map.<span class="title function_">set</span>(<span class="string">&#x27;foo&#x27;</span>, <span class="literal">true</span>);</span><br><span class="line">map.<span class="title function_">set</span>(<span class="string">&#x27;bar&#x27;</span>, <span class="literal">false</span>);</span><br><span class="line"></span><br><span class="line">map.<span class="property">size</span> <span class="comment">// 2</span></span><br></pre></td></tr></table></figure>
<ol>
<li><code>Map</code>的方法大多数和 Set是相同的<ol>
<li><code>set方法</code>表示设置：内部一共有两个参数，第一个参数:表示设置对象的<code>key</code>，第二个参数:表示设置对象的<code>value</code></li>
<li><code>get方法</code>表示获取值：内部的参数表示要获取的对象的<code>key</code></li>
<li><code>delete</code>表示的是删除：参数是要删除对应的<code>key</code></li>
<li><code>has</code>表示内部是否有对应的对象</li>
<li><code>clear</code>方法表示清空</li>
</ol>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// get</span></span><br><span class="line"><span class="keyword">var</span> typeMap = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">typeMap.<span class="title function_">set</span>(<span class="string">&quot;a&quot;</span>,<span class="string">&quot;200&quot;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeMap.<span class="title function_">get</span>(<span class="string">&quot;a&quot;</span>));</span><br><span class="line"><span class="comment">// delete</span></span><br><span class="line"><span class="keyword">let</span> typeMap = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">typeMap.<span class="title function_">set</span>(<span class="string">&quot;a&quot;</span>,<span class="string">&quot;200&quot;</span>);</span><br><span class="line">typeMap.<span class="title function_">delete</span>(<span class="string">&quot;a&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeMap);</span><br><span class="line"><span class="comment">// has</span></span><br><span class="line"><span class="keyword">let</span> typeMap = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">typeMap.<span class="title function_">set</span>(<span class="string">&quot;a&quot;</span>,<span class="string">&quot;200&quot;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeMap.<span class="title function_">has</span>(<span class="string">&quot;a&quot;</span>));</span><br><span class="line"><span class="comment">// clear</span></span><br><span class="line"><span class="keyword">let</span> typeMap = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">typeMap.<span class="title function_">set</span>(<span class="string">&quot;a&quot;</span>,<span class="string">&quot;200&quot;</span>);</span><br><span class="line">typeMap.<span class="title function_">clear</span>()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeMap);</span><br></pre></td></tr></table></figure>
<h3 id="Map的循环方法"><a href="#Map的循环方法" class="headerlink" title="Map的循环方法"></a>Map的循环方法</h3><ol>
<li>循环方法和<code>set</code>是一样的，都支持<code>for..of</code>，<code>forEach</code>，<code>entries</code></li>
<li>比如 <code>for..of</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeMap = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">typeMap.<span class="title function_">set</span>(<span class="string">&quot;a&quot;</span>,<span class="string">&quot;200&quot;</span>);</span><br><span class="line">typeMap.<span class="title function_">set</span>(<span class="string">&quot;b&quot;</span>,<span class="string">&quot;300&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> item <span class="keyword">of</span> typeMap) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>比如遍历keys</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeMap = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">typeMap.<span class="title function_">set</span>(<span class="string">&quot;a&quot;</span>,<span class="string">&quot;200&quot;</span>);</span><br><span class="line">typeMap.<span class="title function_">set</span>(<span class="string">&quot;b&quot;</span>,<span class="string">&quot;300&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> item <span class="keyword">of</span> typeMap.<span class="title function_">keys</span>()) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="WeakMap"><a href="#WeakMap" class="headerlink" title="WeakMap"></a>WeakMap</h3><ol>
<li><code>WeakMap</code>结构与<code>Map</code>结构基本类似，唯一的区别是它<code>只接受对象作为键名</code>（null除外），<code>不接受其他类型的值作为键名</code>，而且键名所指向的对象，<code>不计入垃圾回收机制</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> typeWMap = <span class="keyword">new</span> <span class="title class_">WeakMap</span>();</span><br><span class="line"><span class="keyword">let</span> objKey = &#123;&#125;</span><br><span class="line">typeWMap.<span class="title function_">set</span>(objKey,<span class="string">&quot;200&quot;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(typeWMap);</span><br></pre></td></tr></table></figure>
<ol>
<li><code>WeakMap</code> 和 <code>WeakSet</code> 一样，可用的方法只有<code>get()、set()、has()、delete()</code>。</li>
<li><code>WeakMap</code> 和 <code>WeakSet</code> 的作用是类似的，我们的实际工作中，不会用来进行引用的产出（用来做计算或者遍历等等），主要的作用是辅助 <code>Map</code> 和 <code>Set</code> 的，因为<code>Map</code>和<code>Set</code>是<code>强类型</code>，而 <code>WeakMap</code> 和 <code>WeakSet</code>是<code>弱类型</code>，<code>弱类型的好处是变量会被垃圾机制自动回收，不占用内存</code>，而<code>强类型引用不会</code></li>
</ol>
<h2 id="Proxy"><a href="#Proxy" class="headerlink" title="Proxy"></a>Proxy</h2><h3 id="Proxy的概述"><a href="#Proxy的概述" class="headerlink" title="Proxy的概述"></a>Proxy的概述</h3><ol>
<li><code>Proxy</code> 用于修改某些操作的默认行为，等同于在语言层面做出修改，就是对语言层面上的逻辑进行的修改</li>
<li><code>Proxy</code> 可以理解成，在目标对象之前架设一层 “拦截”，外界对该对象的访问，都必须先通过这层拦截，因此提供了一种机制，可以对外界的访问进行过滤和改写。<code>Proxy</code> 这个词的原意是代理，用在这里表示由它来 “代理” 某些操作，可以译为 “代理器”。</li>
</ol>
<h3 id="Proxy的基本使用"><a href="#Proxy的基本使用" class="headerlink" title="Proxy的基本使用"></a>Proxy的基本使用</h3><ol>
<li>看一下基本使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">    <span class="attr">a</span>: <span class="number">100</span>,</span><br><span class="line">    <span class="attr">b</span>: <span class="number">200</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> proxObj = <span class="keyword">new</span> <span class="title class_">Proxy</span>(obj, &#123;</span><br><span class="line">    <span class="attr">get</span>: <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="comment">// 拦截了既有的操作，返回自己的逻辑</span></span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;获取值的内容&quot;</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">set</span>: <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;设置值的内容&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(proxObj.<span class="property">a</span>);</span><br><span class="line">proxObj.<span class="property">b</span> = <span class="number">200</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(proxObj);</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的 proxObj 是设置可以拦截的对象</li>
<li>第一个 obj 参数是对应要拦截的对象内容</li>
<li>第二个 对象参数是拦截行为，所有的行为在一个对象中</li>
<li>行为的内部可以设置参数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">    <span class="attr">a</span>: <span class="number">100</span>,</span><br><span class="line">    <span class="attr">b</span>: <span class="number">200</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> proxObj = <span class="keyword">new</span> <span class="title class_">Proxy</span>(obj, &#123;</span><br><span class="line">    <span class="attr">get</span>: <span class="keyword">function</span>(<span class="params">target, key</span>) &#123;</span><br><span class="line">        <span class="comment">// 拦截了既有的操作，返回自己的逻辑</span></span><br><span class="line">        <span class="keyword">return</span> <span class="string">`属性<span class="subst">$&#123;key&#125;</span>，属性值：<span class="subst">$&#123;target[key]&#125;</span>`</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">set</span>: <span class="keyword">function</span>(<span class="params">target, key, value</span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`属性<span class="subst">$&#123;key&#125;</span>，属性值：<span class="subst">$&#123;target[key]&#125;</span>，要设置的参数：<span class="subst">$&#123;value&#125;</span>`</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(proxObj.<span class="property">a</span>);</span><br><span class="line">proxObj.<span class="property">b</span> = <span class="number">200</span></span><br></pre></td></tr></table></figure>
<ol>
<li>上面代码</li>
<li><code>get方法</code>主要的参数有两个。<ol>
<li>第一个: <code>target指的目标对象</code></li>
<li>第二个: <code>key表示获取的该对象的key</code></li>
</ol>
</li>
<li><code>set方法</code>主要的参数有三个。<ol>
<li>第一个: <code>target指的目标对象</code></li>
<li>第一个: <code>key表示获取的该对象的key</code></li>
<li>第一个: <code>value表示要设置的value</code></li>
</ol>
</li>
</ol>
<h3 id="Proxy可以当做原型对象"><a href="#Proxy可以当做原型对象" class="headerlink" title="Proxy可以当做原型对象"></a>Proxy可以当做原型对象</h3><ol>
<li>看下面代码</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> proxy = <span class="keyword">new</span> <span class="title class_">Proxy</span>(&#123;&#125;, &#123;</span><br><span class="line">  <span class="attr">get</span>: <span class="keyword">function</span>(<span class="params">target, property</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">35</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> obj = <span class="title class_">Object</span>.<span class="title function_">create</span>(proxy);</span><br><span class="line">obj.<span class="property">time</span> <span class="comment">// 35</span></span><br></pre></td></tr></table></figure>
<h3 id="get方法"><a href="#get方法" class="headerlink" title="get方法"></a>get方法</h3><ol>
<li><code>get</code>方法用于<code>拦截某个属性的读取操作</code>。上文已经有一个例子，下面是另一个拦截读取操作的例子。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> person = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&quot;张三&quot;</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> proxy = <span class="keyword">new</span> <span class="title class_">Proxy</span>(person, &#123;</span><br><span class="line">  <span class="attr">get</span>: <span class="keyword">function</span>(<span class="params">target, property</span>) &#123;</span><br><span class="line">    <span class="comment">// 判断当前的key是否在对应的对象上，也就是查询对象上有没有要查的这个key</span></span><br><span class="line">    <span class="keyword">if</span> (property <span class="keyword">in</span> target) &#123;</span><br><span class="line">      <span class="comment">// 如果有就返回这个值</span></span><br><span class="line">      <span class="keyword">return</span> target[property];</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// 没有则抛出错误</span></span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">ReferenceError</span>(<span class="string">&quot;Property \&quot;&quot;</span> + property + <span class="string">&quot;\&quot; does not exist.&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">proxy.<span class="property">name</span> <span class="comment">// &quot;张三&quot;</span></span><br><span class="line">proxy.<span class="property">age</span> <span class="comment">// 抛出一个错误</span></span><br></pre></td></tr></table></figure>
<ol>
<li><code>get</code>方法内部有三个参数</li>
<li>第一个：<code>target</code>表示接受对象，第二个：是获取的<code>key</code>，第三个：<code>receiver</code>表示操作对象（不常用）</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">    <span class="attr">a</span>: <span class="number">100</span>,</span><br><span class="line">    <span class="attr">b</span>: <span class="number">200</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> proxObj = <span class="keyword">new</span> <span class="title class_">Proxy</span>(obj, &#123;</span><br><span class="line">    <span class="attr">get</span>: <span class="keyword">function</span>(<span class="params">target, key, receiver</span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(receiver)</span><br><span class="line">      <span class="comment">// 拦截了既有的操作，返回自己的逻辑</span></span><br><span class="line">      <span class="keyword">return</span> <span class="string">`属性<span class="subst">$&#123;key&#125;</span>，属性值：<span class="subst">$&#123;target[key]&#125;</span>`</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(proxObj.<span class="property">a</span>);</span><br></pre></td></tr></table></figure>
<h3 id="set方法"><a href="#set方法" class="headerlink" title="set方法"></a>set方法</h3><ol>
<li><code>set</code>方法用来拦截某个属性的赋值操作。</li>
<li><code>set</code>方法一共有4个参数，<ol>
<li>第一个: 参数是接受的对象</li>
<li>第二个: 参数是设置的<code>key</code></li>
<li>第三个: 是设置值</li>
<li>第四个: 参数是操作对象（不常用）</li>
</ol>
</li>
<li>下面是一个案例：比如假定 Person对象有一个 age属性，该属性应该是一个不大于200的整数，那么可以使用Proxy保证age的属性值符合要求</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> validator = &#123;</span><br><span class="line">  <span class="attr">set</span>: <span class="keyword">function</span>(<span class="params">obj, prop, value</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (prop === <span class="string">&#x27;age&#x27;</span>) &#123;</span><br><span class="line">      <span class="keyword">if</span> (!<span class="title class_">Number</span>.<span class="title function_">isInteger</span>(value)) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">TypeError</span>(<span class="string">&#x27;The age is not an integer&#x27;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">if</span> (value &gt; <span class="number">200</span>) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RangeError</span>(<span class="string">&#x27;The age seems invalid&#x27;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 对于age以外的属性，直接保存</span></span><br><span class="line">    obj[prop] = value;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> person = <span class="keyword">new</span> <span class="title class_">Proxy</span>(&#123;&#125;, validator);</span><br><span class="line"></span><br><span class="line">person.<span class="property">age</span> = <span class="number">100</span>;</span><br><span class="line"></span><br><span class="line">person.<span class="property">age</span> <span class="comment">// 100</span></span><br><span class="line">person.<span class="property">age</span> = <span class="string">&#x27;young&#x27;</span> <span class="comment">// 报错</span></span><br><span class="line">person.<span class="property">age</span> = <span class="number">300</span> <span class="comment">// 报错</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// set方法一共有4个参数，第一个参数是接受的对象，第二个参数是设置的key，第三个是设置值，第四个参数是操作对象（不常用）</span></span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">    <span class="attr">a</span>: <span class="number">100</span>,</span><br><span class="line">    <span class="attr">b</span>: <span class="number">200</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> proxObj = <span class="keyword">new</span> <span class="title class_">Proxy</span>(obj, &#123;</span><br><span class="line">    <span class="attr">set</span>: <span class="keyword">function</span>(<span class="params">target, key, value, receiver</span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(receiver);</span><br><span class="line">        <span class="comment">// 拦截了既有的操作，返回自己的逻辑</span></span><br><span class="line">        <span class="keyword">return</span> target[key] = <span class="string">&quot;234&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">proxObj.<span class="property">b</span> = <span class="number">200</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(proxObj);</span><br></pre></td></tr></table></figure>
<h3 id="apply方法"><a href="#apply方法" class="headerlink" title="apply方法"></a>apply方法</h3><ol>
<li><code>apply</code>方法拦截函数的调用、call 和 apply操作。</li>
<li><code>apply</code>方法可以接受三个参数，分别是：目标对象，目标对象的上下文对象（<code>this</code>）和目标对象的参数组</li>
<li>下面是一个例子：</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> twice = &#123;</span><br><span class="line">    <span class="title function_">apply</span>(<span class="params">target, ctx, args</span>) &#123;</span><br><span class="line">        <span class="comment">// Reflect.apply(...arguments)返回是对参数的累加结果</span></span><br><span class="line">        <span class="keyword">return</span> <span class="title class_">Reflect</span>.<span class="title function_">apply</span>(...<span class="variable language_">arguments</span>) * <span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">sum</span>(<span class="params">left, right</span>) &#123;</span><br><span class="line">    <span class="comment">// 累加</span></span><br><span class="line">    <span class="keyword">return</span> left + right;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> proxy = <span class="keyword">new</span> <span class="title class_">Proxy</span>(sum, twice);</span><br><span class="line"><span class="title function_">proxy</span>(<span class="number">1</span>, <span class="number">2</span>) <span class="comment">// 6</span></span><br><span class="line">proxy.<span class="title function_">call</span>(<span class="literal">null</span>, <span class="number">5</span>, <span class="number">6</span>) <span class="comment">// 22</span></span><br><span class="line">proxy.<span class="title function_">apply</span>(<span class="literal">null</span>, [<span class="number">7</span>, <span class="number">8</span>]) <span class="comment">// 30</span></span><br></pre></td></tr></table></figure>
<h3 id="construct方法"><a href="#construct方法" class="headerlink" title="construct方法"></a>construct方法</h3><ol>
<li><code>construct</code>方法用于拦截 <code>new命令</code>，下面是拦截对象的写法。</li>
<li>下面是一个例子</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> <span class="title class_">Proxy</span>(<span class="keyword">function</span>(<span class="params"></span>) &#123;&#125;, &#123;</span><br><span class="line">  <span class="attr">construct</span>: <span class="keyword">function</span>(<span class="params">target, args</span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;called: &#x27;</span> + args.<span class="title function_">join</span>(<span class="string">&#x27;, &#x27;</span>));</span><br><span class="line">    <span class="keyword">return</span> &#123; <span class="attr">value</span>: args[<span class="number">0</span>] * <span class="number">10</span> &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title function_">p</span>(<span class="number">1</span>).<span class="property">value</span></span><br><span class="line"><span class="comment">// &quot;called: 1&quot;</span></span><br><span class="line"><span class="comment">// 10</span></span><br></pre></td></tr></table></figure>
<ol>
<li><code>construct</code> 方法返回的必须是一个对象，否则会报错。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> <span class="title class_">Proxy</span>(<span class="keyword">function</span>(<span class="params"></span>) &#123;&#125;, &#123;</span><br><span class="line">  <span class="attr">construct</span>: <span class="keyword">function</span>(<span class="params">target, argumentsList</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title function_">p</span>() <span class="comment">// 报错</span></span><br></pre></td></tr></table></figure>
<h2 id="Reflect"><a href="#Reflect" class="headerlink" title="Reflect"></a>Reflect</h2><h3 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h3><ol>
<li><code>Reflect</code>和<code>proxy</code>的作用类似，<code>也是代理拦截</code></li>
<li>但是<code>Reflect</code>主要面对的是内部语言的操作对象与<code>Proxy</code>对象一样，也是ES6为了操作对象而提供的<code>新API</code>。<code>Reflect对象</code>的设计目的有这样几个。<br>(1) 将<code>Object对象</code>的一些明显属于语言内部的方法（比如Object.defineProperty），放到<code>Reflect对象</code>上。现阶段，某些方法同时在<code>Object</code>和<code>Reflect对象</code>上部署，未来的新方法将只部署在<code>Reflect对象</code>上。<br>(2) 修改某些<code>Object方法</code>的返回结果，让其变得更合理。比如，<code>Object.defineProperty(obj, name, desc)</code>在无法定义属性时，会抛出一个错误，而<code>Reflect.defineProperty(obj, name, desc)</code>则会返回<code>false</code>。<br>(3) 让<code>Object</code>操作都变成函数行为。某些<code>Object</code>操作是命令式，比如<code>name in obj</code>和<code>delete obj[name]</code>，而<code>Reflect.has(obj, name)</code>和<code>Reflect.deleteProperty(obj, name)</code>让它们变成了函数行为。<br>(4) <code>Reflect对象</code>的方法与<code>Proxy对象</code>的方法一一对应，只要是<code>Proxy对象</code>的方法，就能在<code>Reflect对象</code>上找到对应的方法。这就让<code>Proxy对象</code>可以方便地调用对应的<code>Reflect方法</code>，完成默认行为，作为修改行为的基础。也就是说，不管<code>Proxy</code>怎么修改默认行为，你总可以在<code>Reflect</code>上获取默认行为</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 老写法</span></span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">  <span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(target, property, attributes);</span><br><span class="line">  <span class="comment">// success</span></span><br><span class="line">&#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">  <span class="comment">// failure</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 新写法</span></span><br><span class="line"><span class="keyword">if</span> (<span class="title class_">Reflect</span>.<span class="title function_">defineProperty</span>(target, property, attributes)) &#123;</span><br><span class="line">  <span class="comment">// success</span></span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">  <span class="comment">// failure</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 老写法</span></span><br><span class="line"><span class="string">&#x27;assign&#x27;</span> <span class="keyword">in</span> <span class="title class_">Object</span> <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 新写法</span></span><br><span class="line"><span class="title class_">Reflect</span>.<span class="title function_">has</span>(<span class="title class_">Object</span>, <span class="string">&#x27;assign&#x27;</span>) <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Proxy</span>(target, &#123;</span><br><span class="line">  <span class="attr">set</span>: <span class="keyword">function</span>(<span class="params">target, name, value, receiver</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> success = <span class="title class_">Reflect</span>.<span class="title function_">set</span>(target,name, value, receiver);</span><br><span class="line">    <span class="keyword">if</span> (success) &#123;</span><br><span class="line">      <span class="title function_">log</span>(<span class="string">&#x27;property &#x27;</span> + name + <span class="string">&#x27; on &#x27;</span> + target + <span class="string">&#x27; set to &#x27;</span> + value);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> success;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ol>
<li>上面代码中，<code>Proxy</code>方法拦截<code>target</code>对象的属性赋值行为。它采用<code>Reflect.set</code>方法将值赋值给对象的属性，然后再部署额外的功能。</li>
</ol>
<h3 id="Reflect对象的方法"><a href="#Reflect对象的方法" class="headerlink" title="Reflect对象的方法"></a>Reflect对象的方法</h3><ol>
<li><code>Reflect</code>对象的方法清单如下，共13个。<ol>
<li>Reflect.apply(target,thisArg,args)</li>
<li>Reflect.construct(target,args)</li>
<li>Reflect.get(target,name,receiver)</li>
<li>Reflect.set(target,name,value,receiver)</li>
<li>Reflect.defineProperty(target,name,desc)</li>
<li>Reflect.deleteProperty(target,name)</li>
<li>Reflect.has(target,name)</li>
<li>Reflect.ownKeys(target)</li>
<li>Reflect.isExtensible(target)</li>
<li>Reflect.preventExtensions(target)</li>
<li>Reflect.getOwnPropertyDescriptor(target, name)</li>
<li>Reflect.getPrototypeOf(target)</li>
<li>Reflect.setPrototypeOf(target, prototype)</li>
</ol>
</li>
</ol>
<h2 id="Symbol"><a href="#Symbol" class="headerlink" title="Symbol"></a>Symbol</h2><h3 id="概述-1"><a href="#概述-1" class="headerlink" title="概述"></a>概述</h3><ol>
<li>ES5的对象属性名都是字符串，这容易造成属性名的冲突。</li>
<li>比如，你使用了一个他人提供的对象，但又想为这个对象添加新的方法（mixin模式），新方法的名字就有可能与现有方法产生冲突。如果有一种机制，保证每个属性的名字都是独一无二的就好了，这样就从根本上防止属性名的冲突。这就是ES6引入<code>Symbol</code>的原因。</li>
<li><code>symbol</code>是一种新的数据类型</li>
<li>数据类型分为基本类型值和引用类型值</li>
<li>基本类型值：<code>Number、String、Boolean、undefined、null</code></li>
<li>引用类型值：<code>Object、Array、Function、Date</code>等等</li>
<li><code>Symbol</code>的特性就是<code>唯一性</code></li>
<li><code>Symbol（符号）</code>是一种新的<code>基本类型值</code></li>
</ol>
<h3 id="基本使用-4"><a href="#基本使用-4" class="headerlink" title="基本使用"></a>基本使用</h3><ol>
<li><code>Symbol</code>的使用就是<code>直接圆括号调用，不能通过new来构造</code></li>
<li>我们看一下基本使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="title class_">Symbol</span>()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a);</span><br></pre></td></tr></table></figure>
<ol>
<li><code>Symbol</code>内部可以传入参数，参数的作用是对这个<code>符合的描述</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="title class_">Symbol</span>(<span class="string">&quot;mashibing&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a);</span><br></pre></td></tr></table></figure>
<h3 id="Symbol的唯一性"><a href="#Symbol的唯一性" class="headerlink" title="Symbol的唯一性"></a>Symbol的唯一性</h3><ol>
<li><code>Symbol</code>是代表<code>唯一</code>的意思，同值的<code>Symbol</code>是不相等的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="title class_">Symbol</span>()</span><br><span class="line"><span class="keyword">let</span> b = <span class="title class_">Symbol</span>()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a == b); <span class="comment">// false</span></span><br></pre></td></tr></table></figure>
<ol>
<li>即使内部传入参数相同也不相等</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="title class_">Symbol</span>(<span class="string">&quot;mashibing&quot;</span>)</span><br><span class="line"><span class="keyword">let</span> b = <span class="title class_">Symbol</span>(<span class="string">&quot;mashibing&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a == b); <span class="comment">// false</span></span><br></pre></td></tr></table></figure>
<h3 id="Symbol的内部参数"><a href="#Symbol的内部参数" class="headerlink" title="Symbol的内部参数"></a>Symbol的内部参数</h3><ol>
<li><code>Symbol</code>内部如果是<code>字符串</code>表示当前这个<code>符号的描述信息</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="title class_">Symbol</span>(<span class="string">&quot;mashibing&quot;</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li><code>Symbol</code>内部如果是<code>对象，并且有toString方法，</code>返回的就是这个<code>符号的描述</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="title class_">Symbol</span>(&#123;</span><br><span class="line">    <span class="attr">a</span>: <span class="number">100</span>,</span><br><span class="line">    <span class="attr">toString</span>: <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;symbol的描述信息&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a);</span><br></pre></td></tr></table></figure>
<ol>
<li><code>Symbol</code>内部如果是<code>数组</code>，内部的参数会被<code>扁平化，用逗号隔开</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="title class_">Symbol</span>([</span><br><span class="line">    <span class="number">1</span>,</span><br><span class="line">    <span class="number">2</span>,</span><br><span class="line">    <span class="string">&#x27;a&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;b&#x27;</span></span><br><span class="line">])</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a);</span><br></pre></td></tr></table></figure>
<h3 id="Symbol的应用场景"><a href="#Symbol的应用场景" class="headerlink" title="Symbol的应用场景"></a>Symbol的应用场景</h3><ol>
<li>我们可以用<code>Symbol</code>来做什么？</li>
<li>我们可以用<code>Symbol</code>来创建对象的<code>内部属性</code>，内部属性的特点是<code>防止外部获取或者随意篡改</code></li>
<li>调用时，用[] 包裹</li>
<li>取值时，用[] 包裹</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> sym = <span class="title class_">Symbol</span>(<span class="string">&quot;objKey&quot;</span>)</span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">    <span class="attr">a</span>: <span class="number">1</span>,</span><br><span class="line">    <span class="attr">b</span>: <span class="number">2</span>,</span><br><span class="line">    <span class="attr">c</span>: <span class="number">3</span>,</span><br><span class="line">    [sym]: <span class="number">300</span></span><br><span class="line">&#125;</span><br><span class="line">obj.<span class="property">c</span> = <span class="number">5</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj);</span><br></pre></td></tr></table></figure>
<ol>
<li>此时你会发现，<code>Symbol</code>定义的属性，外部是无法获取的，因为我们知道<code>Symbol</code>同值是不相等的。所以下面的途径是获取不到的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">obj[<span class="title class_">Symbol</span>(<span class="string">&quot;objKey&quot;</span>)]</span><br></pre></td></tr></table></figure>
<ol>
<li>上面的结果会返回<code>undefined</code>，因为<code>symbol(&quot;objKey&quot;) != symbol(&quot;objKey&quot;)</code></li>
<li>并且对象遍历<code>symbol</code>的时候是得不到这个<code>key</code>的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> sym = <span class="title class_">Symbol</span>(<span class="string">&quot;objKey&quot;</span>)</span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">    <span class="attr">a</span>: <span class="number">1</span>,</span><br><span class="line">    <span class="attr">b</span>: <span class="number">2</span>,</span><br><span class="line">    <span class="attr">c</span>: <span class="number">3</span>,</span><br><span class="line">    [sym]: <span class="number">300</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> item <span class="keyword">in</span> obj) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(item);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>再或者使用<code>Object.keys</code>方法也不能获取 <code>symbol</code> 对应的 <code>key</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">keys</span>(obj));</span><br></pre></td></tr></table></figure>
<h3 id="获取对象中Symbol的key的方法"><a href="#获取对象中Symbol的key的方法" class="headerlink" title="获取对象中Symbol的key的方法"></a>获取对象中Symbol的key的方法</h3><ol>
<li>第一个方法是<code>Object.getOwnPropertySymbols</code>，返回的是只有<code>symbol</code>定义的<code>key</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> sym = <span class="title class_">Symbol</span>(<span class="string">&quot;objKey&quot;</span>)</span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">    <span class="attr">a</span>: <span class="number">1</span>,</span><br><span class="line">    <span class="attr">b</span>: <span class="number">2</span>,</span><br><span class="line">    <span class="attr">c</span>: <span class="number">3</span>,</span><br><span class="line">    [sym]: <span class="number">300</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> result = <span class="title class_">Object</span>.<span class="title function_">getOwnPropertySymbols</span>(obj)</span><br></pre></td></tr></table></figure>
<ol>
<li>第二个方法是 <code>Reflect.ownKeys</code>，返回的是所有的 <code>key</code>，包含 <code>symbol</code> 定义的<code>key</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Reflect</span>.<span class="title function_">ownKeys</span>(obj)</span><br></pre></td></tr></table></figure>
<ol>
<li>通过上面的方法，我们还是可以获取对象中<code>symbol</code> 对应的值的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> num = obj[<span class="title class_">Object</span>.<span class="title function_">getOwnPropertySymbols</span>(obj)[<span class="number">0</span>]] <span class="comment">// 300</span></span><br></pre></td></tr></table></figure>
<h3 id="共享符号"><a href="#共享符号" class="headerlink" title="共享符号"></a>共享符号</h3><ol>
<li>我们上面注册的都是普通符号，我们也可以注册共享符号</li>
<li>普通符号</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="title class_">Symbol</span>()</span><br></pre></td></tr></table></figure>
<ol>
<li>共享符号</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="title class_">Symbol</span>.<span class="title function_">for</span>()</span><br></pre></td></tr></table></figure>
<ol>
<li><code>.for()</code>就代表创建了一个共享的符号，内部参数也是描述信息</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> sFb = <span class="title class_">Symbol</span>.<span class="title function_">for</span>(<span class="string">&quot;b&quot;</span>);</span><br><span class="line"><span class="keyword">let</span> sFb2 = <span class="title class_">Symbol</span>.<span class="title function_">for</span>(<span class="string">&quot;b&quot;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(sFb == sFb2); <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<ol>
<li>看上面的结果返回的是true，机理是：<code>Symbol.for()</code>定义的符号代表<code>共享符号</code></li>
<li>如果创建了共享符号，此时就相当于在<code>全局创建了一个符号</code>，此时如果再次创建相同描述的符号，就不会再创建新的了，而是将原来的抛出，所以结果是相等的</li>
<li><code>Symbol.keyFor</code>方法来<code>获取</code>已经注册到全局的<code>共享符号的描述信息</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> sFb2 = <span class="title class_">Symbol</span>.<span class="title function_">for</span>(<span class="string">&quot;b&quot;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Symbol</span>.<span class="title function_">keyFor</span>(sFb2));</span><br></pre></td></tr></table></figure>
<h3 id="Symbol的注意事项"><a href="#Symbol的注意事项" class="headerlink" title="Symbol的注意事项"></a>Symbol的注意事项</h3><ol>
<li><code>Symbol值</code>不能与其他类型的值进行运算，会报错</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> sym = <span class="title class_">Symbol</span>(<span class="string">&#x27;My symbol&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;your symbol is &quot;</span> + sym  <span class="comment">// 报错Cannot convert a Symbol value to a string</span></span><br></pre></td></tr></table></figure>
<ol>
<li>但是，<code>Symbol</code>值可以<code>显式转为字符串</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> sym = <span class="title class_">Symbol</span>(<span class="string">&#x27;My symbol&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="title class_">String</span>(sym) <span class="comment">// &#x27;Symbol(My symbol)&#x27;</span></span><br><span class="line">sym.<span class="title function_">toString</span>() <span class="comment">// &#x27;Symbol(My symbol)&#x27;</span></span><br></pre></td></tr></table></figure>
<ol>
<li><code>Symbol值</code>也可以<code>转为布尔值</code>，但是<code>不能转为数值</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> sym = <span class="title class_">Symbol</span>();</span><br><span class="line"><span class="title class_">Boolean</span>(sym) <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line"><span class="title class_">Number</span>(sym) <span class="comment">// TypeError</span></span><br><span class="line">sym + <span class="number">2</span> <span class="comment">// TypeError</span></span><br></pre></td></tr></table></figure>
<h2 id="字符串的Unicode"><a href="#字符串的Unicode" class="headerlink" title="字符串的Unicode"></a>字符串的Unicode</h2><ol>
<li>什么是<code>Unicode</code>？</li>
<li>世界上存在着多种编码方式，同一个二进制数字可以被解释成不同的符号。因此，要想打开一个文本文件，就必须知道它的编码方式，否则用错误的编码方式解读，就会出现乱码。为什么电子邮件常常出现乱码？就是因为发信人和收信人使用的编码方式不一样。</li>
<li>可以想象，如果有一种编码，将世界上所有的符号都纳入其中。</li>
<li>每一个符号都给予一个独一无二的编码，那么乱码问题就会消失。这就是Unicode，就像它的名字都表示的，这是一种所有符号的编码。</li>
<li><code>Unicode当然是一个很大的集合</code>，现在的规模可以容纳100多万个符号。</li>
<li>每个符号的编码都不一样，比如，U+0639表示阿拉伯字母Ain，U+0041表示英语的大写字母A，U+4E25表示汉字’严’。</li>
<li>具体的符号对应表，可以查询unicode.org，或者专门的汉字对应表</li>
<li>JavaScript允许采用 \uxxxx形式表示一个字符，其中“xxxx”表示字符的码点</li>
<li>比如”\u0061”表示的就是a</li>
<li>但是，这种表示法只限于\u0000——\uFFFF之间的字符。超出这个范围的字符，必须用两个双字节的形式表达。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;\uD842\uDFB7&quot;</span></span><br><span class="line"><span class="comment">// &quot;𠮷&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="string">&quot;\u20BB7&quot;</span></span><br><span class="line"><span class="comment">// &quot; 7&quot;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>上面代码表示，如果直接在\u后面跟上超过0xFFFF的数值（比如\u20BB7），JavaScript会理解成\u20BB+7。由于\u20BB是一个不可打印字符，所以只会显示一个空格，后面跟着一个7</li>
<li>ES6 对这一点做出了改进，只要将码点放入大括号，就能正确解读该字符。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;\u&#123;20BB7&#125;&quot;</span></span><br><span class="line"><span class="comment">// &quot;𠮷&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="string">&quot;\u&#123;41&#125;\u&#123;42&#125;\u&#123;43&#125;&quot;</span></span><br><span class="line"><span class="comment">// &quot;ABC&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> hello = <span class="number">123</span>;</span><br><span class="line">hell\u&#123;6F&#125; <span class="comment">// 123</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;\u&#123;1F680&#125;&#x27;</span> === <span class="string">&#x27;\uD83D\uDE80&#x27;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>具体的方法可以参考文档：<a target="_blank" rel="noopener" href="http://caibaojian.com/es6/string.html">http://caibaojian.com/es6/string.html</a></li>
<li>Unicode编码排序不用记，需要用到的时候可以查转换：<a target="_blank" rel="noopener" href="http://tool.chinaz.com/tools/unicode.aspx">http://tool.chinaz.com/tools/unicode.aspx</a></li>
</ol>
<h2 id="数值的扩展"><a href="#数值的扩展" class="headerlink" title="数值的扩展"></a>数值的扩展</h2><h3 id="二进制和八进制表示法"><a href="#二进制和八进制表示法" class="headerlink" title="二进制和八进制表示法"></a>二进制和八进制表示法</h3><ol>
<li>ES6提供了二进制和八进制数值的新的写法，分别用前缀0b（或0B）和0o（或0O）表示。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">0b111110111</span> === <span class="number">503</span> <span class="comment">// true</span></span><br><span class="line"><span class="number">0o767</span> === <span class="number">503</span> <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<ol>
<li>从ES5开始，在严格模式之中，八进制就不再允许使用前缀0表示，ES6进一步明确，要使用前缀0o表示。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 非严格模式</span></span><br><span class="line">(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">0o11</span> === <span class="number">011</span>);</span><br><span class="line">&#125;)() <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 严格模式</span></span><br><span class="line">(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="string">&#x27;use strict&#x27;</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">0o11</span> === <span class="number">011</span>);</span><br><span class="line">&#125;)() <span class="comment">// Uncaught SyntaxError: Octal literals are not allowed in strict mode.</span></span><br></pre></td></tr></table></figure>
<ol>
<li>如果要将0b和0o前缀的字符串数值转为十进制，要使用Number方法。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Number</span>(<span class="string">&#x27;0b111&#x27;</span>)  <span class="comment">// 7</span></span><br><span class="line"><span class="title class_">Number</span>(<span class="string">&#x27;0o10&#x27;</span>)  <span class="comment">// 8</span></span><br></pre></td></tr></table></figure>
<h3 id="数值的常用扩展方法"><a href="#数值的常用扩展方法" class="headerlink" title="数值的常用扩展方法"></a>数值的常用扩展方法</h3><ol>
<li>数值扩展的方法参考：<a target="_blank" rel="noopener" href="http://caibaojian.com/es6/string.html">http://caibaojian.com/es6/string.html</a></li>
<li>下面我罗列一些常用的主要的方法</li>
<li>Number.isNaN()用来检查一个值是否为NaN。</li>
<li>和传统的方法区别是不会隐式转换</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Number</span>.<span class="built_in">isNaN</span>(<span class="title class_">NaN</span>) <span class="comment">// true</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="built_in">isNaN</span>(<span class="number">15</span>) <span class="comment">// false</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="built_in">isNaN</span>(<span class="string">&#x27;15&#x27;</span>) <span class="comment">// false</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="built_in">isNaN</span>(<span class="literal">true</span>) <span class="comment">// false</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="built_in">isNaN</span>(<span class="number">9</span>/<span class="title class_">NaN</span>) <span class="comment">// true</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="built_in">isNaN</span>(<span class="string">&#x27;true&#x27;</span>/<span class="number">0</span>) <span class="comment">// true</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="built_in">isNaN</span>(<span class="string">&#x27;true&#x27;</span>/<span class="string">&#x27;true&#x27;</span>) <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<ol>
<li>ES6将全局方法parseInt()和parseFloat()，移植到Number对象上面，行为完全保持不变。</li>
<li>这样做的目的，是逐步减少全局性方法，使得语言逐步模块化。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ES5的写法</span></span><br><span class="line"><span class="built_in">parseInt</span>(<span class="string">&#x27;12.34&#x27;</span>) <span class="comment">// 12</span></span><br><span class="line"><span class="built_in">parseFloat</span>(<span class="string">&#x27;123.45#&#x27;</span>) <span class="comment">// 123.45</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// ES6的写法</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="built_in">parseInt</span>(<span class="string">&#x27;12.34&#x27;</span>) <span class="comment">// 12</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="built_in">parseFloat</span>(<span class="string">&#x27;123.45#&#x27;</span>) <span class="comment">// 123.45</span></span><br></pre></td></tr></table></figure>
<ol>
<li>Number.isInteger()用来判断一个值是否为整数</li>
<li>需要注意的是，在JavaScript内部，整数和浮点数是同样的储存方法，所以3和3.0被视为同一个值。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Number</span>.<span class="title function_">isInteger</span>(<span class="number">25</span>) <span class="comment">// true</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="title function_">isInteger</span>(<span class="number">25.0</span>) <span class="comment">// true</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="title function_">isInteger</span>(<span class="number">25.1</span>) <span class="comment">// false</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="title function_">isInteger</span>(<span class="string">&quot;15&quot;</span>) <span class="comment">// false</span></span><br><span class="line"><span class="title class_">Number</span>.<span class="title function_">isInteger</span>(<span class="literal">true</span>) <span class="comment">// false</span></span><br></pre></td></tr></table></figure>
<h3 id="Math方法的扩展"><a href="#Math方法的扩展" class="headerlink" title="Math方法的扩展"></a>Math方法的扩展</h3><ol>
<li>Math.trunc方法用于去除一个数的小数部分，返回整数部分，会进行隐式转换</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Math</span>.<span class="title function_">trunc</span>(<span class="number">4.1</span>) <span class="comment">// 4</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">trunc</span>(<span class="number">4.9</span>) <span class="comment">// 4</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">trunc</span>(-<span class="number">4.1</span>) <span class="comment">// -4</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">trunc</span>(-<span class="number">4.9</span>) <span class="comment">// -4</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">trunc</span>(-<span class="number">0.1234</span>) <span class="comment">// -0</span></span><br></pre></td></tr></table></figure>
<ol>
<li>Math.sign方法用来判断一个数到底是正数、负数、还是零。<ol>
<li>参数为正数，返回+1；</li>
<li>参数为负数，返回-1；</li>
<li>参数为0，返回0；</li>
<li>参数为-0，返回-0;</li>
<li>其他值，返回NaN。</li>
</ol>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Math</span>.<span class="title function_">sign</span>(-<span class="number">5</span>) <span class="comment">// -1</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">sign</span>(<span class="number">5</span>) <span class="comment">// +1</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">sign</span>(<span class="number">0</span>) <span class="comment">// +0</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">sign</span>(-<span class="number">0</span>) <span class="comment">// -0</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">sign</span>(<span class="title class_">NaN</span>) <span class="comment">// NaN</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">sign</span>(<span class="string">&#x27;foo&#x27;</span>); <span class="comment">// NaN</span></span><br><span class="line"><span class="title class_">Math</span>.<span class="title function_">sign</span>();      <span class="comment">// NaN</span></span><br></pre></td></tr></table></figure>
<h2 id="正则表达式的扩展"><a href="#正则表达式的扩展" class="headerlink" title="正则表达式的扩展"></a>正则表达式的扩展</h2><h3 id="语法的修改"><a href="#语法的修改" class="headerlink" title="语法的修改"></a>语法的修改</h3><ol>
<li>在ES6之前定义正则有两种方式</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="string">&#x27;xyz&#x27;</span>, <span class="string">&#x27;i&#x27;</span>);</span><br><span class="line"><span class="comment">// 等价于</span></span><br><span class="line"><span class="keyword">var</span> regex = <span class="regexp">/xyz/i</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>此时定义正则有了新的改变</li>
<li><code>ES5不允许此时使用第二个参数，添加修饰符，否则会报错</code>，但是ES6可以了，下面的代码不会报错</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> regex = <span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="regexp">/xyz/</span>, <span class="string">&#x27;i&#x27;</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>如果<code>RegExp构造函数</code>第一个参数是一个正则对象，那么可以使用<code>第二个参数指定修饰符</code>。而且，返回的正则表达式会忽略原有的正则表达式的修饰符，只使用新指定的修饰符。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="regexp">/abc/ig</span>, <span class="string">&#x27;i&#x27;</span>).<span class="property">flags</span> <span class="comment">// &quot;i&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="修饰符和属性"><a href="#修饰符和属性" class="headerlink" title="修饰符和属性"></a>修饰符和属性</h3><h4 id="u修饰符"><a href="#u修饰符" class="headerlink" title="u修饰符"></a>u修饰符</h4><ol>
<li>ES6对正则表达式添加了<code>u修饰符</code>，含义为<code>“Unicode模式”</code>，用来正确处理<code>大于\uFFFF的Unicode字符</code>。也就是说，会正确处理四个字节的UTF-16编码。</li>
<li>我们看一下u修饰符的作用，比如下面的字符编码是四个字节的’\uD83D\uDC2A’，如果没有使用u修饰符</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/^\uD83D/.<span class="title function_">test</span>(<span class="string">&#x27;\uD83D\uDC2A&#x27;</span>) <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<ol>
<li>上面的结果返回的是true，是因为进行匹配内部匹配到了就返回true</li>
<li>再看一下u修饰符</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/^\uD83D/u.<span class="title function_">test</span>(<span class="string">&#x27;\uD83D\uDC2A&#x27;</span>) <span class="comment">// false</span></span><br></pre></td></tr></table></figure>
<ol>
<li>返回 false是因为全部匹配，根据大于\uFFFF的Unicode字符正确处理</li>
</ol>
<h4 id="y修饰符"><a href="#y修饰符" class="headerlink" title="y修饰符"></a>y修饰符</h4><ol>
<li>除了<code>u修饰符</code>，ES6还为正则表达式添加了<code>y修饰符</code>，叫做<code>“粘连”（sticky）修饰符</code>。</li>
<li><code>y修饰符</code>的作用与<code>g修饰符</code>类似，也是<code>全局匹配</code>，后一次匹配都从上一次匹配成功的下一个位置开始。</li>
<li>不同之处在于，g修饰符只要剩余位置中存在匹配就可，而 y修饰符确保匹配必须从<code>剩余的第一个位置开始</code>，这也就是<code>“粘连”</code>的涵义。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> s = <span class="string">&#x27;aaa_aa_a&#x27;</span>;</span><br><span class="line"><span class="keyword">var</span> r1 = <span class="regexp">/a+/g</span>;</span><br><span class="line"><span class="keyword">var</span> r2 = <span class="regexp">/a+/y</span>;</span><br><span class="line"></span><br><span class="line">r1.<span class="title function_">exec</span>(s) <span class="comment">// [&quot;aaa&quot;]</span></span><br><span class="line">r2.<span class="title function_">exec</span>(s) <span class="comment">// [&quot;aaa&quot;]</span></span><br><span class="line"></span><br><span class="line">r1.<span class="title function_">exec</span>(s) <span class="comment">// [&quot;aa&quot;]</span></span><br><span class="line">r2.<span class="title function_">exec</span>(s) <span class="comment">// null</span></span><br></pre></td></tr></table></figure>
<h4 id="sticky属性"><a href="#sticky属性" class="headerlink" title="sticky属性"></a>sticky属性</h4><ol>
<li>与y修饰符相匹配，ES6的正则对象多了<code>sticky属性</code>，表示是否设置了 y修饰符。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> r = <span class="regexp">/hello\d/y</span>;</span><br><span class="line">r.<span class="property">sticky</span> <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<h4 id="flags属性"><a href="#flags属性" class="headerlink" title="flags属性"></a>flags属性</h4><ol>
<li>ES6为正则表达式新增了 <code>flags属性</code>，会返回正则表达式的修饰符。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ES5的source属性</span></span><br><span class="line"><span class="comment">// 返回正则表达式的正文</span></span><br><span class="line">/abc/ig.<span class="property">source</span></span><br><span class="line"><span class="comment">// &quot;abc&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// ES6的flags属性</span></span><br><span class="line"><span class="comment">// 返回正则表达式的修饰符</span></span><br><span class="line">/abc/ig.<span class="property">flags</span></span><br><span class="line"><span class="comment">// &#x27;gi&#x27;</span></span><br></pre></td></tr></table></figure>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="http://example.com">晚夜微雨问海棠</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="http://example.com/posts/50839dad.html">http://example.com/posts/50839dad.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="http://example.com" target="_blank">晚夜微雨问海棠のBlog</a>！</span></div></div><div class="tag_share"><div class="post_share"><div class="social-share" data-image="https://s1.ax1x.com/2022/11/09/zS8LRA.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://s1.ax1x.com/2022/11/15/zE9P7d.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/15/zE9P7d.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="https://s1.ax1x.com/2022/11/15/zE9ung.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/15/zE9ung.jpg" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/954c8db1.html" title="Google_V8原理"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2023/06/14/pCn45LT.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-06-14</div><div class="title">Google_V8原理</div></div></a></div><div><a href="/posts/f418d067.html" title="H5基础"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNllfe.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-06</div><div class="title">H5基础</div></div></a></div><div><a href="/posts/3da79d5b.html" title="JavaScript入门"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/12/08/z2ar8O.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-21</div><div class="title">JavaScript入门</div></div></a></div><div><a href="/posts/f818a4a.html" title="JavaScript面向对象"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/06/xXrY34.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-11-06</div><div class="title">JavaScript面向对象</div></div></a></div><div><a href="/posts/3a5743c3.html" title="Node全栈"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrV6Q1.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-12-03</div><div class="title">Node全栈</div></div></a></div><div><a href="/posts/c02b1e8e.html" title="PHP服务器&#x2F;Ajax"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/17/zmFYzd.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-11-17</div><div class="title">PHP服务器&#x2F;Ajax</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div class="vcomment" id="vcomment"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content is-expand"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#ECMAScript-%EF%BC%88ES6%EF%BC%89"><span class="toc-number">1.</span> <span class="toc-text">ECMAScript （ES6）</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#ECMAScript-%E7%AE%80%E4%BB%8B"><span class="toc-number">1.1.</span> <span class="toc-text">ECMAScript 简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#let-%E5%92%8C-const%E5%91%BD%E4%BB%A4"><span class="toc-number">1.2.</span> <span class="toc-text">let 和 const命令</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#le-%E5%92%8C-const%E9%83%BD%E6%9C%89%E5%9D%97%E7%BA%A7%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">1.2.1.</span> <span class="toc-text">le 和 const都有块级作用域</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#let%E5%92%8Cconst%E5%A3%B0%E6%98%8E%E7%9A%84%E5%8F%98%E9%87%8F%E9%83%BD%E6%B2%A1%E6%9C%89%E5%A3%B0%E6%98%8E%E6%8F%90%E5%8D%87"><span class="toc-number">1.2.2.</span> <span class="toc-text">let和const声明的变量都没有声明提升</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#let-%E5%92%8C-const-%E6%98%AF%E4%BC%9A%E5%87%BA%E7%8E%B0%E6%9A%82%E6%97%B6%E6%80%A7%E6%AD%BB%E5%8C%BA"><span class="toc-number">1.2.3.</span> <span class="toc-text">let 和 const 是会出现暂时性死区</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#let%E5%AE%9A%E4%B9%89%E7%9A%84%E6%98%AF%E5%8F%98%E9%87%8F%EF%BC%8Cconst%E5%AE%9A%E4%B9%89%E7%9A%84%E6%98%AF%E5%B8%B8%E9%87%8F"><span class="toc-number">1.2.4.</span> <span class="toc-text">let定义的是变量，const定义的是常量</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#let-%E5%92%8C-const%E5%AE%9A%E4%B9%89%E7%9A%84%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E4%B8%8D%E6%98%AF-window%E7%9A%84%E5%B1%9E%E6%80%A7"><span class="toc-number">1.2.5.</span> <span class="toc-text">let 和 const定义的全局变量不是 window的属性</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8F%98%E9%87%8F%E7%9A%84%E8%A7%A3%E6%9E%84%E5%92%8C%E8%B5%8B%E5%80%BC"><span class="toc-number">1.3.</span> <span class="toc-text">变量的解构和赋值</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E8%A7%A3%E6%9E%84"><span class="toc-number">1.3.1.</span> <span class="toc-text">自动解构</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A7%A3%E6%9E%84%E6%98%AF%E4%B8%80%E4%B8%80%E5%AF%B9%E5%BA%94%E7%9A%84%EF%BC%8C%E6%97%A0%E8%AE%BA%E5%86%85%E9%83%A8%E7%BB%93%E6%9E%84%E5%A4%9A%E5%A4%8D%E6%9D%82"><span class="toc-number">1.3.2.</span> <span class="toc-text">解构是一一对应的，无论内部结构多复杂</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0"><span class="toc-number">1.3.3.</span> <span class="toc-text">剩余参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%BC%BA%E5%88%B6%E7%BB%93%E6%9E%84"><span class="toc-number">1.3.4.</span> <span class="toc-text">强制结构</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E8%A7%A3%E6%9E%84%E5%92%8C%E8%B5%8B%E5%80%BC"><span class="toc-number">1.3.5.</span> <span class="toc-text">字符串的解构和赋值</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%89%A9%E5%B1%95"><span class="toc-number">1.4.</span> <span class="toc-text">字符串的扩展</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E9%81%8D%E5%8E%86"><span class="toc-number">1.4.1.</span> <span class="toc-text">字符串的遍历</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#includes%E3%80%81startsWidth%E3%80%81endsWith%E6%96%B9%E6%B3%95"><span class="toc-number">1.4.2.</span> <span class="toc-text">includes、startsWidth、endsWith方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#repeat%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.4.3.</span> <span class="toc-text">repeat字符串循环</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#padStart%E5%92%8CpadEnd%E8%A1%A5%E5%85%A8%E6%96%B9%E6%B3%95"><span class="toc-number">1.4.4.</span> <span class="toc-text">padStart和padEnd补全方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A8%A1%E6%9D%BF%E5%AD%97%E7%AC%A6%E4%B8%B2%E2%98%85"><span class="toc-number">1.4.5.</span> <span class="toc-text">模板字符串★</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%B0%E7%BB%84%E7%9A%84%E6%89%A9%E5%B1%95%E2%98%85"><span class="toc-number">1.5.</span> <span class="toc-text">数组的扩展★</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#forEach%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.1.</span> <span class="toc-text">forEach方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#map%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.2.</span> <span class="toc-text">map方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#filter%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.3.</span> <span class="toc-text">filter方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#reduce%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.4.</span> <span class="toc-text">reduce方法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#reduce%E7%9A%84%E6%9C%BA%E7%90%86"><span class="toc-number">1.5.4.1.</span> <span class="toc-text">reduce的机理</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%BC%E5%90%88%E5%BA%94%E7%94%A8"><span class="toc-number">1.5.5.</span> <span class="toc-text">综合应用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#includes%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.6.</span> <span class="toc-text">includes方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#find-%E5%92%8C-findIndex%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.7.</span> <span class="toc-text">find 和 findIndex方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Array-from%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.8.</span> <span class="toc-text">Array.from方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Array-of%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.9.</span> <span class="toc-text">Array.of方法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%89%A9%E5%B1%95"><span class="toc-number">1.6.</span> <span class="toc-text">对象的扩展</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E5%8F%AF%E4%BB%A5%E7%9C%81%E7%95%A5v"><span class="toc-number">1.6.1.</span> <span class="toc-text">对象可以省略v</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%96%B9%E6%B3%95%E7%AE%80%E5%86%99"><span class="toc-number">1.6.2.</span> <span class="toc-text">对象的方法简写</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Object-keys-%E5%92%8C-Object-values"><span class="toc-number">1.6.3.</span> <span class="toc-text">Object.keys 和 Object.values</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Object-is%E6%96%B9%E6%B3%95"><span class="toc-number">1.6.4.</span> <span class="toc-text">Object.is方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Object-assign%E6%96%B9%E6%B3%95"><span class="toc-number">1.6.5.</span> <span class="toc-text">Object.assign方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E4%B8%AD%E7%9A%84%E5%8A%A8%E6%80%81%E9%94%AE-%E6%96%B9%E6%8B%AC%E5%8F%B7"><span class="toc-number">1.6.6.</span> <span class="toc-text">对象中的动态键-方括号</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#for%E2%80%A6in%E6%96%B9%E6%B3%95"><span class="toc-number">1.6.7.</span> <span class="toc-text">for…in方法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%9A%84%E6%89%A9%E5%B1%95"><span class="toc-number">1.7.</span> <span class="toc-text">函数的扩展</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0"><span class="toc-number">1.7.1.</span> <span class="toc-text">箭头函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87"><span class="toc-number">1.7.2.</span> <span class="toc-text">箭头函数的上下文</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#bind%E6%96%B9%E6%B3%95"><span class="toc-number">1.7.3.</span> <span class="toc-text">bind方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E9%BB%98%E8%AE%A4%E5%8F%82%E6%95%B0"><span class="toc-number">1.7.4.</span> <span class="toc-text">函数默认参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E4%B8%8D%E7%BB%91%E5%AE%9A-arguments%E5%8F%82%E6%95%B0"><span class="toc-number">1.7.5.</span> <span class="toc-text">箭头函数不绑定 arguments参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E2%80%A6rest%E5%8F%82%E6%95%B0"><span class="toc-number">1.7.6.</span> <span class="toc-text">…rest参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E4%B8%8D%E5%8F%AF%E4%BB%A5%E5%BD%93%E5%81%9A%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0"><span class="toc-number">1.7.7.</span> <span class="toc-text">箭头函数不可以当做构造函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E6%B2%A1%E6%9C%89%E5%8E%9F%E5%9E%8B%E5%B1%9E%E6%80%A7-prototype"><span class="toc-number">1.7.8.</span> <span class="toc-text">箭头函数没有原型属性 prototype</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E4%B8%8D%E8%83%BD%E8%BF%9B%E8%A1%8C%E5%8F%98%E9%87%8F%E5%A3%B0%E6%98%8E%E6%8F%90%E5%8D%87"><span class="toc-number">1.7.9.</span> <span class="toc-text">箭头函数不能进行变量声明提升</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%9A%84%E5%8F%82%E6%95%B0%E4%B9%9F%E5%8F%AF%E4%BB%A5%E8%BF%9B%E8%A1%8C%E8%A7%A3%E6%9E%84"><span class="toc-number">1.7.10.</span> <span class="toc-text">函数的参数也可以进行解构</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%A5%E6%A0%BC%E6%A8%A1%E5%BC%8F"><span class="toc-number">1.7.11.</span> <span class="toc-text">严格模式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E4%B8%8A%E4%B8%8B%E6%96%87%E7%9A%84%E5%B0%8F%E7%BB%83%E4%B9%A0"><span class="toc-number">1.7.12.</span> <span class="toc-text">箭头函数上下文的小练习</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%A2%98%E7%9B%AE1%EF%BC%9A"><span class="toc-number">1.7.12.1.</span> <span class="toc-text">题目1：</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%A2%98%E7%9B%AE2%EF%BC%9A"><span class="toc-number">1.7.12.2.</span> <span class="toc-text">题目2：</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%A2%98%E7%9B%AE3%EF%BC%9A"><span class="toc-number">1.7.12.3.</span> <span class="toc-text">题目3：</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#class%E7%B1%BB%E7%9A%84%E5%A2%9E%E5%8A%A0"><span class="toc-number">1.8.</span> <span class="toc-text">class类的增加</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%9A%E4%B9%89%E2%80%9C%E7%B1%BB%E2%80%9D"><span class="toc-number">1.8.1.</span> <span class="toc-text">定义“类”</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%A7%E6%89%BF"><span class="toc-number">1.8.2.</span> <span class="toc-text">继承</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#constructor%E6%96%B9%E6%B3%95"><span class="toc-number">1.8.3.</span> <span class="toc-text">constructor方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#class%E7%B1%BB%E5%AE%9A%E4%B9%89%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E6%B2%A1%E6%9C%89%E5%8F%98%E9%87%8F%E5%A3%B0%E6%98%8E%E7%9A%84%E6%8F%90%E5%8D%87"><span class="toc-number">1.8.4.</span> <span class="toc-text">class类定义的构造函数没有变量声明的提升</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%A7%E6%89%BF%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E5%BF%85%E9%A1%BB%E8%A6%81%E5%9C%A8constructor%E4%B8%AD%E8%B0%83%E7%94%A8super%E5%90%A6%E5%88%99%E4%BC%9A%E6%8A%A5%E9%94%99"><span class="toc-number">1.8.5.</span> <span class="toc-text">继承的构造函数必须要在constructor中调用super否则会报错</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Object-getPrototypeOf%E6%96%B9%E6%B3%95"><span class="toc-number">1.8.6.</span> <span class="toc-text">Object.getPrototypeOf方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#super%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">1.8.7.</span> <span class="toc-text">super关键字</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%9A%84get%E5%92%8Cset%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">1.8.8.</span> <span class="toc-text">函数的get和set关键字</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95"><span class="toc-number">1.8.9.</span> <span class="toc-text">静态方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#new-target%E5%B1%9E%E6%80%A7"><span class="toc-number">1.8.10.</span> <span class="toc-text">new.target属性</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#babel%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">1.9.</span> <span class="toc-text">babel的基本使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Promise%E5%AF%B9%E8%B1%A1%EF%BC%88%E2%98%85%EF%BC%89"><span class="toc-number">1.10.</span> <span class="toc-text">Promise对象（★）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise%E7%9A%84%E5%90%AB%E4%B9%89"><span class="toc-number">1.10.1.</span> <span class="toc-text">Promise的含义</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A4%8D%E4%B9%A0%E5%BC%82%E6%AD%A5%E5%92%8C%E5%90%8C%E6%AD%A5"><span class="toc-number">1.10.2.</span> <span class="toc-text">复习异步和同步</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%BC%82%E6%AD%A5%E7%9A%84%E8%AF%AD%E6%B3%95%E7%BC%BA%E7%82%B9"><span class="toc-number">1.10.3.</span> <span class="toc-text">异步的语法缺点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">1.10.4.</span> <span class="toc-text">Promise的基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%9D%9ENode%E7%8E%AF%E5%A2%83%E4%BD%BF%E7%94%A8Promise"><span class="toc-number">1.10.5.</span> <span class="toc-text">非Node环境使用Promise</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise-resolve-%E6%96%B9%E6%B3%95"><span class="toc-number">1.10.6.</span> <span class="toc-text">Promise.resolve 方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise-all%E6%96%B9%E6%B3%95"><span class="toc-number">1.10.7.</span> <span class="toc-text">Promise.all方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise-race%E6%96%B9%E6%B3%95"><span class="toc-number">1.10.8.</span> <span class="toc-text">Promise.race方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise-done%E6%96%B9%E6%B3%95-%E9%9D%9EES6%E6%8F%90%E4%BE%9B"><span class="toc-number">1.10.9.</span> <span class="toc-text">Promise.done方法-非ES6提供</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise-finally-%E6%96%B9%E6%B3%95-%E9%9D%9EES6%E6%8F%90%E4%BE%9B"><span class="toc-number">1.10.10.</span> <span class="toc-text">Promise.finally 方法-非ES6提供</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Iterator%E9%81%8D%E5%8E%86%E5%99%A8"><span class="toc-number">1.11.</span> <span class="toc-text">Iterator遍历器</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Iterator%EF%BC%88%E9%81%8D%E5%8E%86%E5%99%A8%EF%BC%89%E7%9A%84%E6%A6%82%E5%BF%B5"><span class="toc-number">1.11.1.</span> <span class="toc-text">Iterator（遍历器）的概念</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Iterator%E7%9A%84%E6%A8%A1%E6%8B%9F%E5%B0%81%E8%A3%85"><span class="toc-number">1.11.2.</span> <span class="toc-text">Iterator的模拟封装</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%9A%84%E9%BB%98%E8%AE%A4-Iterator%E6%8E%A5%E5%8F%A3"><span class="toc-number">1.11.3.</span> <span class="toc-text">数据结构的默认 Iterator接口</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#for-of%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.11.4.</span> <span class="toc-text">for..of循环</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Generator-%E5%87%BD%E6%95%B0"><span class="toc-number">1.12.</span> <span class="toc-text">Generator 函数</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Generator%E6%A6%82%E5%BF%B5"><span class="toc-number">1.12.1.</span> <span class="toc-text">Generator概念</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">1.12.2.</span> <span class="toc-text">基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Generator%E7%9A%84return%E9%97%AE%E9%A2%98"><span class="toc-number">1.12.3.</span> <span class="toc-text">Generator的return问题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#yield%E8%AF%AD%E5%8F%A5"><span class="toc-number">1.12.4.</span> <span class="toc-text">yield语句</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E7%94%9F%E6%88%90-iterator%E9%81%8D%E5%8E%86%E5%99%A8"><span class="toc-number">1.12.5.</span> <span class="toc-text">对象生成 iterator遍历器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Generator-%E7%9A%84-return%E6%96%B9%E6%B3%95"><span class="toc-number">1.12.6.</span> <span class="toc-text">Generator 的 return方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#yield"><span class="toc-number">1.12.7.</span> <span class="toc-text">yield*</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Generator%E7%9A%84%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">1.12.8.</span> <span class="toc-text">Generator的应用场景</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#async%E5%92%8Cawait"><span class="toc-number">1.13.</span> <span class="toc-text">async和await</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8-1"><span class="toc-number">1.13.1.</span> <span class="toc-text">基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#async%E5%87%BD%E6%95%B0"><span class="toc-number">1.13.2.</span> <span class="toc-text">async函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#await%E5%91%BD%E4%BB%A4"><span class="toc-number">1.13.3.</span> <span class="toc-text">await命令</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#async%E5%87%BD%E6%95%B0%E7%9A%84%E9%94%99%E8%AF%AF%E6%9C%BA%E5%88%B6%E9%97%AE%E9%A2%98"><span class="toc-number">1.13.4.</span> <span class="toc-text">async函数的错误机制问题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#async%E5%87%BD%E6%95%B0%E7%9A%84%E5%A4%9A%E7%A7%8D%E4%BD%BF%E7%94%A8%E5%BD%A2%E5%BC%8F"><span class="toc-number">1.13.5.</span> <span class="toc-text">async函数的多种使用形式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#for-await-of%E9%81%8D%E5%8E%86%E5%BC%82%E6%AD%A5"><span class="toc-number">1.13.6.</span> <span class="toc-text">for await..of遍历异步</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#fetch%E8%AF%B7%E6%B1%82"><span class="toc-number">1.14.</span> <span class="toc-text">fetch请求</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8-2"><span class="toc-number">1.14.1.</span> <span class="toc-text">基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#fetch%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9"><span class="toc-number">1.14.2.</span> <span class="toc-text">fetch的优缺点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#fetch-%E5%92%8C-jquery-%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">1.14.3.</span> <span class="toc-text">fetch 和 jquery 的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#fetch%E7%9A%84%E8%AF%B7%E6%B1%82"><span class="toc-number">1.14.4.</span> <span class="toc-text">fetch的请求</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Set-%E5%92%8C-WeakSet"><span class="toc-number">1.15.</span> <span class="toc-text">Set 和 WeakSet</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Set%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">1.15.1.</span> <span class="toc-text">Set的基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Set%E7%9A%84%E6%96%B9%E6%B3%95"><span class="toc-number">1.15.2.</span> <span class="toc-text">Set的方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8Eset%E7%9A%84%E5%BE%AA%E7%8E%AF"><span class="toc-number">1.15.3.</span> <span class="toc-text">关于set的循环</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#set-%E8%BD%AC%E6%8D%A2%E4%B8%BA%E6%95%B0%E7%BB%84"><span class="toc-number">1.15.4.</span> <span class="toc-text">set 转换为数组</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakSet-%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-number">1.15.5.</span> <span class="toc-text">WeakSet 的使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakSet%E7%9A%84%E6%96%B9%E6%B3%95"><span class="toc-number">1.15.6.</span> <span class="toc-text">WeakSet的方法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Map-%E5%92%8C-WeakMap"><span class="toc-number">1.16.</span> <span class="toc-text">Map 和 WeakMap</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8-3"><span class="toc-number">1.16.1.</span> <span class="toc-text">基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Map%E7%9A%84key%E5%8F%AF%E4%BB%A5%E6%98%AF%E4%BB%BB%E6%84%8F%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.16.2.</span> <span class="toc-text">Map的key可以是任意类型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Map%E7%9A%84%E6%96%B9%E6%B3%95%E5%92%8C%E5%B1%9E%E6%80%A7"><span class="toc-number">1.16.3.</span> <span class="toc-text">Map的方法和属性</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Map%E7%9A%84%E5%BE%AA%E7%8E%AF%E6%96%B9%E6%B3%95"><span class="toc-number">1.16.4.</span> <span class="toc-text">Map的循环方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakMap"><span class="toc-number">1.16.5.</span> <span class="toc-text">WeakMap</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Proxy"><span class="toc-number">1.17.</span> <span class="toc-text">Proxy</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Proxy%E7%9A%84%E6%A6%82%E8%BF%B0"><span class="toc-number">1.17.1.</span> <span class="toc-text">Proxy的概述</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Proxy%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">1.17.2.</span> <span class="toc-text">Proxy的基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Proxy%E5%8F%AF%E4%BB%A5%E5%BD%93%E5%81%9A%E5%8E%9F%E5%9E%8B%E5%AF%B9%E8%B1%A1"><span class="toc-number">1.17.3.</span> <span class="toc-text">Proxy可以当做原型对象</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#get%E6%96%B9%E6%B3%95"><span class="toc-number">1.17.4.</span> <span class="toc-text">get方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#set%E6%96%B9%E6%B3%95"><span class="toc-number">1.17.5.</span> <span class="toc-text">set方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#apply%E6%96%B9%E6%B3%95"><span class="toc-number">1.17.6.</span> <span class="toc-text">apply方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#construct%E6%96%B9%E6%B3%95"><span class="toc-number">1.17.7.</span> <span class="toc-text">construct方法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Reflect"><span class="toc-number">1.18.</span> <span class="toc-text">Reflect</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A6%82%E8%BF%B0"><span class="toc-number">1.18.1.</span> <span class="toc-text">概述</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Reflect%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%96%B9%E6%B3%95"><span class="toc-number">1.18.2.</span> <span class="toc-text">Reflect对象的方法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Symbol"><span class="toc-number">1.19.</span> <span class="toc-text">Symbol</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A6%82%E8%BF%B0-1"><span class="toc-number">1.19.1.</span> <span class="toc-text">概述</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8-4"><span class="toc-number">1.19.2.</span> <span class="toc-text">基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Symbol%E7%9A%84%E5%94%AF%E4%B8%80%E6%80%A7"><span class="toc-number">1.19.3.</span> <span class="toc-text">Symbol的唯一性</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Symbol%E7%9A%84%E5%86%85%E9%83%A8%E5%8F%82%E6%95%B0"><span class="toc-number">1.19.4.</span> <span class="toc-text">Symbol的内部参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Symbol%E7%9A%84%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">1.19.5.</span> <span class="toc-text">Symbol的应用场景</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%8E%B7%E5%8F%96%E5%AF%B9%E8%B1%A1%E4%B8%ADSymbol%E7%9A%84key%E7%9A%84%E6%96%B9%E6%B3%95"><span class="toc-number">1.19.6.</span> <span class="toc-text">获取对象中Symbol的key的方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B1%E4%BA%AB%E7%AC%A6%E5%8F%B7"><span class="toc-number">1.19.7.</span> <span class="toc-text">共享符号</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Symbol%E7%9A%84%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9"><span class="toc-number">1.19.8.</span> <span class="toc-text">Symbol的注意事项</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84Unicode"><span class="toc-number">1.20.</span> <span class="toc-text">字符串的Unicode</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%B0%E5%80%BC%E7%9A%84%E6%89%A9%E5%B1%95"><span class="toc-number">1.21.</span> <span class="toc-text">数值的扩展</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%92%8C%E5%85%AB%E8%BF%9B%E5%88%B6%E8%A1%A8%E7%A4%BA%E6%B3%95"><span class="toc-number">1.21.1.</span> <span class="toc-text">二进制和八进制表示法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E5%80%BC%E7%9A%84%E5%B8%B8%E7%94%A8%E6%89%A9%E5%B1%95%E6%96%B9%E6%B3%95"><span class="toc-number">1.21.2.</span> <span class="toc-text">数值的常用扩展方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Math%E6%96%B9%E6%B3%95%E7%9A%84%E6%89%A9%E5%B1%95"><span class="toc-number">1.21.3.</span> <span class="toc-text">Math方法的扩展</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E6%89%A9%E5%B1%95"><span class="toc-number">1.22.</span> <span class="toc-text">正则表达式的扩展</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AF%AD%E6%B3%95%E7%9A%84%E4%BF%AE%E6%94%B9"><span class="toc-number">1.22.1.</span> <span class="toc-text">语法的修改</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BF%AE%E9%A5%B0%E7%AC%A6%E5%92%8C%E5%B1%9E%E6%80%A7"><span class="toc-number">1.22.2.</span> <span class="toc-text">修饰符和属性</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#u%E4%BF%AE%E9%A5%B0%E7%AC%A6"><span class="toc-number">1.22.2.1.</span> <span class="toc-text">u修饰符</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#y%E4%BF%AE%E9%A5%B0%E7%AC%A6"><span class="toc-number">1.22.2.2.</span> <span class="toc-text">y修饰符</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#sticky%E5%B1%9E%E6%80%A7"><span class="toc-number">1.22.2.3.</span> <span class="toc-text">sticky属性</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#flags%E5%B1%9E%E6%80%A7"><span class="toc-number">1.22.2.4.</span> <span class="toc-text">flags属性</span></a></li></ol></li></ol></li></ol></li></ol></div></div></div></div></main><footer id="footer" style="background-image: url('https://s1.ax1x.com/2022/11/09/zS8LRA.jpg')"><div id="footer-wrap"><div class="copyright">&copy;2022 - 2023 By 晚夜微雨问海棠</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="chat_btn" type="button" title="聊天"><i class="fas fa-sms"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div id="rightMenu"><div class="rightMenu-group rightMenu-small"><div class="rightMenu-item" id="menu-backward"><i class="fa-solid fa-arrow-left"></i></div><div class="rightMenu-item" id="menu-forward"><i class="fa-solid fa-arrow-right"></i></div><div class="rightMenu-item" id="menu-refresh"><i class="fa-solid fa-arrow-rotate-right"></i></div><div class="rightMenu-item" id="menu-home"><i class="fa-solid fa-house"></i></div></div><div class="rightMenu-group rightMenu-line rightMenuOther"><a class="rightMenu-item menu-link" href="/archives/"><i class="fa-solid fa-archive"></i><span>文章归档</span></a><a class="rightMenu-item menu-link" href="/categories/"><i class="fa-solid fa-folder-open"></i><span>文章分类</span></a><a class="rightMenu-item menu-link" href="/tags/"><i class="fa-solid fa-tags"></i><span>文章标签</span></a></div><div class="rightMenu-group rightMenu-line rightMenuNormal"><div class="rightMenu-item" id="menu-translate"><i class="fa-solid fa-earth-asia"></i><span>繁简切换</span></div><div class="rightMenu-item" id="menu-darkmode"><i class="fa-solid fa-moon"></i><span>切换模式</span></div></div></div><div id="rightmenu-mask"></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><script>var preloader = {
  endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")

  }
}
window.addEventListener('load',preloader.endLoading())</script><div class="js-pjax"><script>(() => {
  const $mermaidWrap = document.querySelectorAll('#article-container .mermaid-wrap')
  if ($mermaidWrap.length) {
    window.runMermaid = () => {
      window.loadMermaid = true
      const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'default'

      Array.from($mermaidWrap).forEach((item, index) => {
        const mermaidSrc = item.firstElementChild
        const mermaidThemeConfig = '%%{init:{ \'theme\':\'' + theme + '\'}}%%\n'
        const mermaidID = 'mermaid-' + index
        const mermaidDefinition = mermaidThemeConfig + mermaidSrc.textContent
        mermaid.mermaidAPI.render(mermaidID, mermaidDefinition, (svgCode) => {
          mermaidSrc.insertAdjacentHTML('afterend', svgCode)
        })
      })
    }

    const loadMermaid = () => {
      window.loadMermaid ? runMermaid() : getScript('https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js').then(runMermaid)
    }

    window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
  }
})()</script><script>function loadValine () {
  function initValine () {
    const valine = new Valine(Object.assign({
      el: '#vcomment',
      appId: '',
      appKey: '',
      avatar: 'monsterid',
      serverURLs: '',
      emojiMaps: "",
      path: window.location.pathname,
      visitor: false
    }, null))
  }

  if (typeof Valine === 'function') initValine() 
  else getScript('https://cdn.jsdelivr.net/npm/valine/dist/Valine.min.js').then(initValine)
}

if ('Valine' === 'Valine' || !true) {
  if (true) btf.loadComment(document.getElementById('vcomment'),loadValine)
  else setTimeout(loadValine, 0)
} else {
  function loadOtherComment () {
    loadValine()
  }
}</script></div><div class="aplayer no-destroy" data-id="7625372994" data-server="netease" data-type="playlist" data-fixed="true" data-autoplay="true"> </div> <script defer src="https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js"></script> <script src="/swiper/swiper.min.js"></script> <script src="/swiper/swiperindex.js"></script> <script src="//cdn.bootcss.com/pace/1.0.2/pace.min.js"></script> <script src="/js/title.js"></script> <script defer data-pjax src="/js/cat.js"></script> <script defer data-pjax src="/js/rightMenu.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = false;
POWERMODE.mobile = false;
document.body.addEventListener('input', POWERMODE);
</script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/click-heart.min.js" async="async" mobile="false"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show","#web_bg",".js-pjax"]

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener scroll 
  window.tocScrollFn && window.removeEventListener('scroll', window.tocScrollFn)
  window.scrollCollect && window.removeEventListener('scroll', scrollCollect)

  typeof preloader === 'object' && preloader.initLoading()
  document.getElementById('rightside').style.cssText = "opacity: ''; transform: ''"
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

  typeof disqusjs === 'object' && disqusjs.destroy()
})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof chatBtnFn === 'function' && chatBtnFn()
  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()

  typeof preloader === 'object' && preloader.endLoading()
})

document.addEventListener('pjax:error', (e) => {
  if (e.request.status === 404) {
    pjax.loadUrl('/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><!-- hexo injector body_end start --><script data-pjax>function history_calendar_injector_config(){
                var parent_div_git = document.getElementsByClassName('sticky_layout')[0];
                var item_html = '<div class="card-widget card-history"><div class="card-content"><div class="item-headline"><i class="fas fa-clock fa-spin"></i><span>那年今日</span></div><div id="history-baidu" style="height: 100px;overflow: hidden"><div class="history_swiper-container" id="history-container" style="width: 100%;height: 100%"><div class="swiper-wrapper" id="history_container_wrapper" style="height:20px"></div></div></div></div>';
                console.log('已挂载history_calendar')
                // parent_div_git.innerHTML=item_html+parent_div_git.innerHTML // 无报错，但不影响使用(支持pjax跳转)
                parent_div_git.insertAdjacentHTML("afterbegin",item_html) // 有报错，但不影响使用(支持pjax跳转)
            }if( document.getElementsByClassName('sticky_layout')[0] && (location.pathname ==='/'|| '/' ==='all')){

            history_calendar_injector_config()
        } </script><script data-pjax  src="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.js"></script><script data-pjax src="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-card-history/baiduhistory/js/main.js"></script><script data-pjax>
    function butterfly_categories_card_injector_config(){
      var parent_div_git = document.getElementById('recent-posts');
      var item_html = '<style>li.categoryBar-list-item{width:24%;}.categoryBar-list{max-height: 190px;overflow:auto;}.categoryBar-list::-webkit-scrollbar{width:0!important}@media screen and (max-width: 650px){.categoryBar-list{max-height: 160px;}}</style><div class="recent-post-item" style="height:auto;width:100%;padding:0px;"><div id="categoryBar"><ul class="categoryBar-list"><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpicnew6.photophoto.cn%2F20120106%2Fhaimianbaobaotupian-10036689_1.jpg&amp;refer=http%3A%2F%2Fpicnew6.photophoto.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648815&amp;t=a3deb15ddd7a38597964c3a05e519bd7);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/Asp-Net/&quot;);" href="javascript:void(0);">Asp.Net</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/site-backgound.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/C-系列/&quot;);" href="javascript:void(0);">C#系列</a><span class="categoryBar-list-count">8</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13012860773%2F1000.jpg&amp;refer=http%3A%2F%2Finews.gtimg.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648865&amp;t=1d2f13b52a7e279e8801545f59eda4e7);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/Hexo重装记录/&quot;);" href="javascript:void(0);">Hexo重装记录</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202011%2F07%2F20201107183300_ac0c5.thumb.1000_0.jpeg&amp;refer=http%3A%2F%2Fc-ssl.duitang.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648887&amp;t=3d32c6b12a4cf12e5cec3585b79c1fc3);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/EF/&quot;);" href="javascript:void(0);">EF</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic%2F25%2Feb%2F1f%2F25eb1fd40b5a740c2b79e33f700806e5.jpg&amp;refer=http%3A%2F%2Fup.enterdesk.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648908&amp;t=6425ee3bd166b0f5c5ffa6fb18b6937b);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/LOL/&quot;);" href="javascript:void(0);">LOL</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Flmg.jj20.com%2Fup%2Fallimg%2Ftx26%2F36080017392073.jpg&amp;refer=http%3A%2F%2Flmg.jj20.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665650136&amp;t=5cc414d0ee58c9e285218d92f6a95513);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/idea/&quot;);" href="javascript:void(0);">idea</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn10%2F320%2Fw700h420%2F20180907%2F5116-hitesuz6599636.jpg&amp;refer=http%3A%2F%2Fn.sinaimg.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665650004&amp;t=6a304aa9cc7435ec1d148b8f99092bc0);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/世界/&quot;);" href="javascript:void(0);">世界</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxCi6.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/世界见闻录/&quot;);" href="javascript:void(0);">世界见闻录</a><span class="categoryBar-list-count">8</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxFzD.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/前端体系/&quot;);" href="javascript:void(0);">前端体系</a><span class="categoryBar-list-count">19</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxnot.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/副业/&quot;);" href="javascript:void(0);">副业</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxMJf.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/文案/&quot;);" href="javascript:void(0);">文案</a><span class="categoryBar-list-count">6</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxQW8.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/办公日常/&quot;);" href="javascript:void(0);">办公日常</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAx3Qg.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/朝花夕拾/&quot;);" href="javascript:void(0);">朝花夕拾</a><span class="categoryBar-list-count">12</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxYes.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/前端/&quot;);" href="javascript:void(0);">前端</a><span class="categoryBar-list-count">20</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(undefined);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/杂七杂八/&quot;);" href="javascript:void(0);">杂七杂八</a><span class="categoryBar-list-count">7</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(undefined);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/简书/&quot;);" href="javascript:void(0);">简书</a><span class="categoryBar-list-count">5</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(undefined);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/游戏/&quot;);" href="javascript:void(0);">游戏</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li></ul></div></div>';
      console.log('已挂载butterfly_categories_card')
      parent_div_git.insertAdjacentHTML("afterbegin",item_html)
      }
    if( document.getElementById('recent-posts') && (location.pathname ==='/'|| '/' ==='all')){
    butterfly_categories_card_injector_config()
    }
  </script><script data-pjax>
  function butterfly_clock_anzhiyu_injector_config(){
    var parent_div_git = document.getElementsByClassName('sticky_layout')[0];
    var item_html = '<div class="card-widget card-clock"><div class="card-glass"><div class="card-background"><div class="card-content"><div id="hexo_electric_clock"><img class="entered loading" id="card-clock-loading" src= "" data-lazy-src="https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu/lib/loading.gif" style="height: 120px; width: 100%;" data-ll-status="loading"/></div></div></div></div></div>';
    console.log('已挂载butterfly_clock_anzhiyu')
    parent_div_git.insertAdjacentHTML("afterbegin",item_html)
    }
  var elist = 'null'.split(',');
  var cpage = location.pathname;
  var epage = '/';
  var qweather_key = '41ea442da35546559913a6a5d54163b2';
  var gaud_map_key = '6b62fbebf584b9a22a85bfccbf90335e';
  var baidu_ak_key = 'undefined';
  var flag = 0;
  var clock_rectangle = '114.35,34.79';
  var clock_default_rectangle_enable = 'true';

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_clock_anzhiyu_injector_config();
  }
  else if (epage === cpage){
    butterfly_clock_anzhiyu_injector_config();
  }
  </script><script src="https://widget.qweather.net/simple/static/js/he-simple-common.js?v=2.0"></script><script data-pjax src="https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu/lib/clock.min.js"></script><script data-pjax>
  function butterfly_footer_beautify_injector_config(){
    var parent_div_git = document.getElementById('footer-wrap');
    var item_html = '<div id="workboard"></div><p id="ghbdages"><a class="github-badge" target="_blank" href="https://hexo.io/" style="margin-inline:5px" data-title="博客框架为Hexo_v5.4.0" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&amp;logo=hexo" alt=""/></a><a class="github-badge" target="_blank" href="https://butterfly.js.org/" style="margin-inline:5px" data-title="主题版本Butterfly_v4.2.2" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&amp;logo=bitdefender" alt=""/></a><a class="github-badge" target="_blank" href="https://www.jsdelivr.com/" style="margin-inline:5px" data-title="本站使用JsDelivr为静态资源提供CDN加速" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&amp;logo=jsDelivr" alt=""/></a><a class="github-badge" target="_blank" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" style="margin-inline:5px" data-title="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&amp;logo=Claris" alt=""/></a></p>';
    console.log('已挂载butterfly_footer_beautify')
    parent_div_git.insertAdjacentHTML("beforeend",item_html)
    }
  var elist = 'null'.split(',');
  var cpage = location.pathname;
  var epage = 'all';
  var flag = 0;

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_footer_beautify_injector_config();
  }
  else if (epage === cpage){
    butterfly_footer_beautify_injector_config();
  }
  </script><script async src="/js/runtime/runtime.min.js"></script><script data-pjax>
  function butterfly_swiper_injector_config(){
    var parent_div_git = document.getElementById('recent-posts');
    var item_html = '<div class="recent-post-item swiper_container_card" style="height: auto;width: 100%"><div id="random"><div id="random-banner"><canvas id="peoplecanvas"></canvas></div><a id="random-hover" style="width:100%;height:auto;" href="javascript:toRandomPost()" rel="external nofollow noreferrer" one-link-mark="yes"><i class="fa fa-paper-plane" style="margin-left:10px"></i><div style="margin-left:10px">随便逛逛<i class="fa-solid fa-arrow-right" style="margin-left:10px"></i></div></a></div><div class="blog-slider swiper-container-fade swiper-container-horizontal" id="swiper_container"><div class="blog-slider__wrp swiper-wrapper" style="transition-duration: 0ms;"><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/67fcd28d.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://img2.baidu.com/it/u=4087346614,241521689&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=500&amp;h=333" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-19</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/67fcd28d.html&quot;);" href="javascript:void(0);" alt="">学生人到职业人_心态篇</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/67fcd28d.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/8a73f76c.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/04/xLiBTA.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-11-04</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/8a73f76c.html&quot;);" href="javascript:void(0);" alt="">生活の奇思妙想☞2022</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/8a73f76c.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/14e5dae6.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/21/xcAQDH.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-11-12</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/14e5dae6.html&quot;);" href="javascript:void(0);" alt="">少年自负凌云笔</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/14e5dae6.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/9b7092b7.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNJbF0.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-13</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/9b7092b7.html&quot;);" href="javascript:void(0);" alt="">租房有感</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/9b7092b7.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/94bbc7d.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNJLWT.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-25</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/94bbc7d.html&quot;);" href="javascript:void(0);" alt="">谷歌收藏</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/94bbc7d.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/3b350f14.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNJJd1.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-13</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/3b350f14.html&quot;);" href="javascript:void(0);" alt="">阳光不燥、微风正好</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/3b350f14.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div></div><div class="blog-slider__pagination swiper-pagination-clickable swiper-pagination-bullets"></div></div></div>';
    console.log('已挂载butterfly_swiper')
    parent_div_git.insertAdjacentHTML("afterbegin",item_html)
    }
  var elist = 'undefined'.split(',');
  var cpage = location.pathname;
  var epage = '/';
  var flag = 0;

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_swiper_injector_config();
  }
  else if (epage === cpage){
    butterfly_swiper_injector_config();
  }
  </script><script defer src="https://npm.elemecdn.com/anzhiyu-blog@1.1.6/js/swiper.min.js"></script><script defer data-pjax src="https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiper_init.js"></script><script data-pjax src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/gsap/3.9.1/gsap.min.js"></script><script defer src="https://npm.elemecdn.com/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/people.min.js"></script><script async src="/anzhiyu/random.js"></script><div class="js-pjax"><script async="async">var arr = document.getElementsByClassName('recent-post-item');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '1.5s');
    arr[i].setAttribute('data-wow-delay', '200ms');
    arr[i].setAttribute('data-wow-offset', '30');
    arr[i].setAttribute('data-wow-iteration', '1');
  }</script><script async="async">var arr = document.getElementsByClassName('card-widget');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '');
    arr[i].setAttribute('data-wow-delay', '200ms');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('flink-list-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__flipInY');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('flink-list-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__animated');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('article-sort-item');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__slideInRight');
    arr[i].setAttribute('data-wow-duration', '1.5s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('site-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__flipInY');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('site-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__animated');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script></div><script defer src="https://cdn.cbd.int/hexo-butterfly-wowjs/lib/wow.min.js"></script><script defer src="https://cdn.cbd.int/hexo-butterfly-wowjs/lib/wow_init.js"></script><script async src="/js/ali_font.js"></script><!-- hexo injector body_end end --><script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"tagMode":false,"debug":false,"model":{"jsonPath":"/live2dw/assets/koharu.model.json"},"display":{"position":"left","width":150,"height":300},"mobile":{"show":false},"log":false,"pluginJsPath":"lib/","pluginModelPath":"assets/","pluginRootPath":"live2dw/"});</script></body></html>